没有合适的资源?快使用搜索试试~ 我知道了~
sqlite文件格式分析
需积分: 9 11 下载量 68 浏览量
2010-05-21
13:21:19
上传
评论
收藏 357KB DOC 举报
温馨提示
试读
24页
sqlite文件格式分析 网上介绍SQLite文件格式的文章并不少,但一般都是针对小文件:一个表,几条记录,两个页。本文准备一直分析到比较大的文件,至少B-tree和B+tree中得有内结点(就是说不能只有一个既是根又是叶的结点,就是说表中得多点记录,得建索引),还要争取对SQLite的各类页都做出分析。
资源推荐
资源详情
资源评论
SQLite 数据库文件格式全面分析
作者:空转
0 前言
性急的兄弟可以跳过前言直接看第 1 章,特别性急的兄弟可以跳过前面各章,直接看鸣谢。
最近对 SQLite 数据库很感兴趣,认真地学了有半个多月了,越学越觉着好玩。好玩归好玩,
只是目前没什么实际用途,那就写点儿东西吧,否则半个月不是白学了嘛!
SQLite 数据库包括多方面的知识,比如 VDBE 什么的。据说那些东西会经常变。确实,我
用的是 3.6.18 版,我看跟其它文档中描述的 3.3.6 的 VDBE 已经很不一样了。所以决定先写
文件格式,只要是 3.?.?的版本,文件格式应该不会有太大变化吧。
网上介绍 SQLite 文件格式的文章并不少,但一般都是针对小文件:一个表,几条记录,两
个页。本文准备一直分析到比较大的文件,至少 B-tree 和 B+tree 中得有内结点(就是说不能
只有一个既是根又是叶的结点,就是说表中得多点记录,得建索引 ),还要争取对 SQLite
的各类页都做出分析。
在分析的过程中,争取把 SQLite 数据库关于文件格式的基本规定也都介绍一下。这样,本
文既是一个综合性的技术文档,又带有实例说明,兄弟们参考时岂不是就很方便了吗?
既然是技术文档,要想读懂总得先掌握点 SQLite 数据库的基本知识吧。所以,先介绍参考
文献。
0.1 参考文献
1-The Definitive Guide to SQLite . Michael Owens:据说是比较经典的 SQLite 著作,我看写
得是挺好的。边看边翻译了其中的主要部分,但不敢拿出来,大家还是看原文吧。
2-SQLite 源代码:其实有关 SQLite 的最原始说明可能都在源代码中了。把此项列在第 2,
只是因为我是先看的书再看的代码,估计大家也会是这个顺序吧。先浏览一下代码还是很
有收获的,特别是几个主要的.h 文件,对本文的写作很有帮助。有关文件格式的说明主要
在 btreeInt.h 中。
3-SQLite 入门与分析 :网上 Arrowcat 的系列文章。Arrowcat 应该是一个很博学的人,看他
的文章收获很大,在此也算是鸣谢吧。
4-SQLite . Chris Newman:我没看,因为也是网上能够下载到的重要资源,所以也在此列出。
看目录内容应该比参考文献 1 简单一些,但出版日期也更早了一些。
5-NULL:在网上搜了半天,国内为什么就没有关于 SQLite 的好书呢?
6- http://www.sqlite.org/fileformat.html:如果这篇文章看懂了,其实我这篇东西根本就不用
再看了。这是介绍 SQLite 文件格式的权威文档,列在最后,是因为我也是写完这篇东西后
才看到的。该文档由 SQLite 官方网站提供,当初没看,一是因为上网少,还没仔细浏览人
家的网站就开始干了(太激动),其实归根结蒂还是因为英语不好。看到此文档这后还敢把
我的东西发出来,有两个原因:一、为其他英语比我强不了多少的兄弟提供一点方便,二
我这里有例子,看起来更形象一些吧。
0.2 术语
这里不集中讨论大量术语了,那样显得太正式,还真成“文章”了。绝大多数术语都是在出
现时再进行简单解释,但还是有个别概念需要先说明清楚,比如:
(1) Btree、B-tree 和 B+tree:
Btree 是为磁盘存储而优化了的一种树结构,其一般性说明可参考各类《数据结构》教材。
根据实现方法的不同,Btree 又分为很多类型。在 SQLite 中,存储表数据用的是 B+tree,
存储表索引用的是 B-tree。由于历史原因,SQLite 在 3.0 版以前只使用 B-tree,从 3.0 版开
始,才对表数据使用了 B+tree。因此,在 SQLite 的官方文档中,有时 B-tree 表示存储表索
引的 B-tree,有时又是两种 Btree 的统称。本文中将两种 Btree 的概念加以了区分,而将
Btree 作为两种树的统称,这是与 SQLite 官方文档及当前大多数 SQLite 介绍性文档相区别
的地方。
(2) auto-vacuum 数据库:
一般情况下,当一个事务从数据库中删除了数据并提交后,数据库文件的大小保持不变。
即使整页的数据都被删除,该页也会变成“空闲页”等待再次被使用,而不会实际地被从数
据库文件中删除。执行 vacuum 操作,可以通过重建数据库文件来清除数据库内所有的未
用空间,使数据库文件变小。但是,如果一个数据库在创建时被指定为 auto_vacuum 数据
库,当删除事务提交时,数据库文件会自动缩小。使用 auto_vacuum 数据库可以节省空间,
但却会增加数据库操作的时间,有利有弊。Auto_vacuum 数据库需要使用附加的格式,如
指针位图页,本文只讨论非 auto_vacuum 数据库。
(3) 数据库映像、数据库文件和日志文件:
“数据库映像”是 SQLite 数据库的磁盘映像。SQLite 数据库存储在单一的“数据库文件”中。
一般情况下,数据库映像和数据库文件是一致的,可以理解为数据库映像就是数据库文件
的内容,但有例外。如果事务对数据库进行了修改,这些修改会暂存在“日志文件”中,此
时可以认为数据库映像分布在数据库文件和日志文件两个文件中。日志文件有自己的格式
本文不涉及。
(4) SQLite 的当前版本:
我写这篇东西时,SQLite 的当前版本为 3.6.18。等我写完时,已经变成 3.6.19 了,文件格
式没变。
1 小文件的分析
1.1 准备数据库
执行 SQLite 的命令行工具,创建一个新的数据库 food_test.db。
D:\SQLite\CLP>sqlite3 foods_test.db
创建一个新表。
CREATE TABLE foods(
id integer primary key,
type_id integer,
name text );
插入 2 条记录。
INSERT INTO "foods" VALUES(1, 1, 'Bagels');
INSERT INTO "foods" VALUES(2, 1, 'Bagels, raisin');
退出命令行工具。
当前目录下多了一个文件 foods_test.db,大小为 2K。
现在,就可以用 UltraEdit 或 WinHex 之类的软件对其进行分析了。
1.2 SQLite 文件格式
SQLite 有 3 类数据库。除内存数据库外,SQLite 把每个数据库(main 或 temp)都存储到一个
单独的文件中。
SQLite 数据库文件由固定大小的“页(page)”组成。页的大小可以在 512~32768 之间(包含这
两个值,必须是 2 的指数),默认大小为 1024 个字节(1KB)。页大小可以在数据库刚刚创建
时设置,一旦创建了数据库对象之后,这个值就不能再改变了。
数据库中所有的页从 1 开始顺序编号。在具体的实现中,页号用 4 字节来表示(但我没搞清
是否有符号位)。文件的第 1 个页被称为 page 1,第 2 个页被称为 page 2,依此类推。编号
为 0 的页表示“无此页”。
页的类型可以是:Btree 页、空闲(free)页或溢出(overflow)页。Btree 又可以是 B-tree 或
B+tree,每一种树的结点又区分为内部页和叶子页。一个数据库文件中可能没有空闲页或
溢出页,但必然有 Btree 页。关于 Btree 页的格式规定是 SQLite 数据库的核心内容,本文的
前半部分都是在介绍 Btree 页。
注:其实 SQLite 还有两种页。一种称为“锁页(locking page)”。只有 1 页,位于数据库文件
偏移为 1G 开始的地方,如果文件不足 1G,就没有此页。该页是用于文件加锁的区域,不
能存储数据(参源代码 io.h)。好在,如果只是读数据,即使文件大于 1G,也不会有指针指
向此页,因此下面我们就不再提它了。另一种称为 “指针位图页(pointer-map page)”,这类
页用于在 auto-vacuum 的数据库中存储元数据。本文不涉及 auto-vacuum 数据库,也就不讨
论这种页了。
从逻辑上来说,一个 SQLite 数据库文件由多个多重 Btree 构成。每个 Btree 存储一个表的数
据或一个表的索引,索引采用 B-tree,而表数据采用 B+tree,每个 Btree 占用至少一个完整
的页,每个页是 Btree 的一个结点。每个表或索引的第 1 个页称为根页,所有表或索引的根
页编号都存储在系统表 sqlite_master 中,表 sqlite_master 的根页为 page 1。
注:sqlite_master 是一个系统表,保存了数据库的 schema 信息,详参“关于 sqlite_master 表”
一节。
数据库中第一个页(page 1)永远是 Btree 页。Page 1 的前 100 个字节是一个对数据库文件进
行描述的“文件头”。它包括数据库的版本、格式的版本、页大小、编码等所有创建数据库
时设置的永久性参数。关于这个特殊文件头的文档在 btreeInt.h 中,具体格式如下:
偏移量 大小 说明
0 16
头字符串,如果不改源程序,此字符串永远是"SQLite format 3"。
16 2
页大小(以字节为单位)。
18 1
文件格式版本(写)。对于 SQLite 的当前版本,此值为 1。如果该值大
于 1,表示文件为只读。SQLite 将来版本对此域的规定可能改变。
19 1
文件格式版本(读)。对于 SQLite 的当前版本,此值为 1。如果该值大
于 1,SQLite 认为文件格式错,拒绝打开此文件。SQLite 将来版本对
此域的规定可能改变。
20 1
每页尾部保留空间的大小。(留作它用,默认为 0。)
21 1
Btree 内部页中一个单元最多能够使用的空间。
255 意味着 100%,默认值为 0x40,即 64(25%),这保证了一个结点
(页)至少有 4 个单元。
22 1
Btree 内 部 页 中一个 单 元 使用空 间 的 最小值 。 默 认值为 0x20 ,即
32(12.5%)。
23 1
Btree 叶 子 页 中一个 单 元 使用空 间 的 最小值 。 默 认值为 0x20 ,即
32(12.5%)。
注:SQLite 的当前版本规定 21~23 的 3 个字节值只能是 0X402020。原
来这 3 个字节值是可变的,从 3.6.0 版开始被固定下来了。
24 4
文件修改计数,通常被事务使用,由事务增加其值。SQLite 用此域的
值验证内存缓冲区中数据的有效性。
28 4
未使用。
32 4
空闲页链表首指针。参“空闲页”一节。
36 4
文件内空闲页的数量。
40 60
15 个 4 字节的元数据变量。
从偏移 40 开始的 15 个 4 字节元数据变量在 btreeInt.h 中的定义如下:
40 4 Schema 版本:每次 schema 改变(创建或删除表、索引、视图或触发器等对象,
造成 sqlite_master 表被修改)时,此值+1。
44 4 File format of schema layer:当前允许值为 1~4,超过此范围,将被认为是文件格
式错。
48 4 Size of page cache。
52 4 Largest root-page (auto/incr_vacuum):对于 auto-vacuum 数据库,此域为数据库中
根页编号的最大值,非 0。对于非 auto-vacuum 数据库,此域值为 0。
56 4 1=UTF-8、2=UTF16le、3=UTF16be。
60 4 User version。此域值供用户应用程序自由存取,其含义也由用户定义。
64 4 Incremental vacuum mode:对于 auto-vacuum 数据库,如果是 Incremental vacuum
模式,此域值为 1。否则,此域值为 0。
68 4 未使用。
72 4 未使用。
用 UltraEdit 打开文件 foods_test.db,page 1 在 0X0000~0X03FF。其中文件头内容如下(深蓝
色部分):
前 16 个字节为头字符串,程序中固定设为"SQLite format 3"。
0X0400:页大小,0X0400=1024 字节。
0X01:文件格式版本(写),值为 1。
0X01:文件格式版本(读),值为 1。
0X40:Btree 内部页中一个单元最多能够使用的空间。0X40=64,即 25%。
0X20:Btree 内部页中一个单元使用空间的最小值。0X20=32,即 12.5%。
0X20:Btree 叶子页中一个单元使用空间的最小值。0X20=32,即 12.5%。
0X00000003:文件修改计数,现在已经修改了 3 次,分别是 1 次创建和两次插入。
从 0X20 开始的 4 个字节:空闲页链表首指针。当前值为 0,表示该链表为空。
从 0X24 开始的 4 个字节:文件内空闲页的数量。当前值为 0。
从 0X28 开 始 的 4 个 字 节 : Schema version 。 当 前 值 为 0X00000001 。 以 后 , 每 次
sqlite_master 表被修改时,此值+1。
从 0X38 开始的 4 个字节:采用的字符编码。此处为 0X00000001,表示采用的是 UTF-8 编
码。
注意:在 SQLite 文件中,所有的整数都采用大端格式,即高位字节在前。
1.3 Btree 页格式介绍
1.3.1 Btree 页的分区
页的类型有 Btree 页、空闲页和溢出页,本文前 3 章介绍的都是 Btree 页,其他类型的页在
第 4、5 章介绍。
每个 Btree 页由四个部分构成:
剩余23页未读,继续阅读
资源评论
huangwei1024
- 粉丝: 53
- 资源: 12
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功