首先,先介绍一个SQLite3数据库,我能够直观感受到的是单一磁盘文件,就是说SQLite数据库被存在文件系统的单一磁盘文件内(如果有日志文件的话,数据库映像就将存在两个文件中),只要有权限就可以随意的访问和拷贝,而其他的数据库引擎,基本都会将数据库存放在一个磁盘目录下,然后由该目录下的一组文件构成该数据库的数据文件。(以上参考《SQLite 学习手册》)。
下面进入正题,来讲讲SQLite3数据库文件结构。
SQLite3数据库总体结构
SQLite3数据库表的B+树结构
SQLite数据库页面结构
注:以上三张图来自朱清华的论文《基于Android手机SQLite的取证系统设计实现》
SQLite3数据库头结构
用winhex打开一个数据库文件(数据库名.db),前100个字节就是数据库的头结构,这是固定的。如下图:
这100个字节所代表的含义是:
起始地址 终止地址 含义 备注0 15 头字符串 一般都是SQLite format 3
16 17 页大小 表示数据库的页大小,上图为0x1000,也就是4096个字节
18 18 文件格式版本写 一般是0x01
19 19 文件格式版本读 也是0x01
20 20 每页尾部保留空间大小 默认是0
21 21 btree内部页单元最多能用的空间 0x40,也就是25%
22 22 btree内部页单元最少使用空间 0x20,也就是12.5%
23 23 btree叶子页单元最少使用空间 0x20,12.5%
24 27 文件修改次数 该值由事务增加
28 31 数据库占据的总页数
32 35 空闲页链表头指针
我觉得对于在auto-vacuum数据库, 由于空闲页只要出现一个空闲页就将这个空间归还给操作系统,因此,他的空闲页链表头指针一直为0,我查看了一个开启auto-vacuum选项的数据库发现这个值都为0
36 39 空闲页数量 这个也同样都为0
40 44 schema版本号
44 47 值为1-4之间
48 51 默认页缓存大小
52 55 b-tree最大根页号 当创建数据库的时候启动auto-vacuum功能时,此处的值表示b-tree最大的根页号,没有启用该功能时,此处值为0
56 59 编码方式
1对应utf-8,2对应utf-16le,3对应utf-16be
60 63 用户版本号 此处的值由用户使用pragma读取或设置
64 67 是否启用incremental-vacuum 对于auto-vacuum数据库,当为incremental-vacuum时为1
68 71 用户应用程序ID 由pragma application_id设置的应用ID
72 91 保留空间 为扩展空间预留
92 95 有效版本
96 99 SQLite数据库版本号
SQLite3数据库页头结构