1. SQLite 数据类型深度解析
作为一名长期使用SQLite的开发者,我发现很多同行对它的类型系统存在误解。SQLite的动态类型机制与传统数据库截然不同,这种设计带来了灵活性,但也容易引发数据一致性问题。今天我们就来彻底拆解这套类型系统,分享我在实际项目中的使用心得。
SQLite的类型系统包含两个核心概念:存储类(Storage Classes)和类型亲和性(Type Affinity)。存储类决定了数据在磁盘上的物理存储格式,而类型亲和性则是列定义时声明的"偏好类型",用于指导数据插入时的转换行为。这种分离设计让SQLite既能保持轻量级,又能处理各种数据类型。
注意:虽然SQLite允许在INTEGER列中存储字符串,但在生产环境中混合类型会导致查询性能下降和比较运算意外行为,应当避免。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 存储类:数据在磁盘的真实形态
2.1 五种存储类详解
SQLite实际存储数据时只使用以下五种存储格式:
-
NULL
表示缺失或未知的值。与Java中的null不同,SQLite的NULL是一个独立类型。在内存中通常占用1字节标记位,实际存储空间取决于行格式。 -
INTEGER
采用可变长度编码:- 1字节:-127到127
- 2字节:-32,768到32,767
- 3字节:-8,388,608到8,388,607
- 4字节:-2,147,483,648到2,147,483,647
- 6字节:-140,737,488,355,328到140,737,488,355,327
- 8字节:-9,223,372,036,854,775,808到9,223,372,036,854,775,807
实测案例:存储10万条记录时,使用适当范围的INTEGER类型可节省约40%空间。
-
REAL
总是8字节IEEE 754浮点数。与Java的double完全兼容,但要注意精度问题:java复制// Java示例:SQLite REAL与Java double的转换 PreparedStatement stmt = conn.prepareStatement("INSERT INTO test VALUES(?)"); stmt.setDouble(1, 0.1); // 实际存储可能为0.10000000000000000555 -
TEXT
支持三种编码格式:- UTF-8(默认)
- UTF-16BE
- UTF-16LE
存储空间 = 内容字节数 + 终止符(通常1字节)。在Java中使用时要注意字符集转换:
java复制// 确保Java字符串编码与数据库一致 conn.setEncoding("UTF-8"); -
BLOB
二进制大对象,最大长度约140TB(理论值)。实际使用时受以下限制:- 单页默认最大1KB
- 可通过`PRAGMA p
