SQLite3记录格式与官方文档不符的原因咨询
问题解析
你看到的差异来自两个核心关键点:SQLite对小整数的存储优化,以及你混淆了单元格内容和文档中描述的记录本身。
1. SQLite对整数0/1的存储优化
SQLite的序列化类型码中,8和9是专门的空间优化码:
- 类型码
8代表整数0,无需在记录主体中存储任何字节 - 类型码
9代表整数1,同样无需在记录主体中存储数据
你插入的id=1会被自动用类型码9存储,而非你预期的类型码1(1字节整数),这是SQLite为节省空间做的优化。
2. 混淆了单元格与记录的边界
文档中描述的"记录"只是SQLite数据页中单元格的一部分。默认创建的表都带ROWID(除非指定WITHOUT ROWID),完整的单元格结构是:
varint(ROWID) + varint(记录总长度) + 记录本身(头部+主体)
你给出的十六进制内容是完整的单元格,正确拆分如下:
| 部分 | 十六进制 | 含义 |
|---|---|---|
| ROWID | 01 | 单字节varint,值为1(第一条记录的默认ROWID) |
| 记录总长度 | 0E | 单字节varint,值为14(记录的头部+主体总字节数) |
| 记录头部长度 | 03 | 单字节varint,值为3(记录头部总字节数,包含自身) |
| id列的序列化类型码 | 09 | 单字节varint,代表整数1,无需主体数据 |
| name列的序列化类型码 | 23 | 单字节varint,值为35,对应(35-13)/2=11字节的UTF-8文本 |
| name列的主体数据 | 48 65 6C 6C 6F 20 57 6F 72 6C 64 | 11字节的"Hello World" |
验证记录结构
按照文档定义,记录本身完全符合规则:
- 头部:
03 09 23(长度3字节,包含两个类型码) - 主体:仅包含name列的11字节字符串(id列用类型码9优化,无主体数据)
- 记录总长度:3+11=14,与单元格中的
0E一致
你的预期偏差原因
- 未考虑SQLite对
1的优化存储,错误假设使用类型码1而非9 - 将单元格的ROWID和记录长度字段当成了记录的一部分,导致对头部长度的误解
内容的提问来源于stack exchange,提问作者Michael Schäfer
相关产品推荐
相关产品推荐

