数据库头信息存储在根页中,紧接着数据库头的是页头信息,页头可以是中间页页可以是叶子页,当数据库很小的时候,数据库头结束后就是页头,也就是说根页就是叶子页。
上图中蓝色部分就是一个页头信息,页头的结构如下:
起始地址 结束地址 含义 备注0 0 该页类型
0x0d表示b+tree叶子页,0x05是b+tree内部页,0x0a是b-tree叶子页,0x02是b-tree内部页
1 2 第一个自由块的偏移量 指的是第一个自由块的偏移地址,这个地址是相对于该页的页首而言的,因此在数据库中查找的时候需要换算成绝对偏移量,也就是加上该页页头的偏移量
3 4 本页单元数
5 6 单元内容起始地址 这个起始地址是数据库存储的最新的那条记录的地址
7 7 空闲块数 指的是空闲块大小小于3个字节的数目
8 11 最右孩子页号 只有内部页有这一属性,叶子页是没有的
12 12+本页单元数*2 该页中每个单元的起始地址 这个地址也是一个相对量,实际使用的时候需要换算
将上面的表格和页头信息相对应可以发现,数据库头结束后紧跟的是一个b+tree内部页页头,该页没有自由块,共有5个单元,单元内容的起始地址是0x0FE7,空闲块数为0。最右孩子页号为0x00001B,接下来10个字节分别代表该页五个单元的起始偏移。在0x0FE7后面可以看到还有其他的信息,这些信息就是被部分覆盖前的原始信息。
接下来看一个b+tree叶子页的详细情况:
可以发现上面该页的页头标志是0x0D,也就是叶子页,并且该页有被删除的数据,他的第一个自由块的起始地址是0x0729,该页有14个单元,单元内容起始地址是0x0122,空闲块数是0,该页每一最右孩子页号这一个区域。
SQLite3数据库Sql_master表结构
同样的Sqli_master表页存储在根页中。Sql_master表是系统表,它里面存储着各个表的建表SQL语句,下面是Sql_master表的详细结构:
type name tal_name rootpage sqltext字段,系统表的创建类型,有table,index,trigger,view四种类型 text字段,表、索引、触发器、视图的名字 对表和视图来说,这个值和name字段一致,对索引和触发器来说是建立在那个表上的表名字 对表和索引来说是根页的页号,至今看到的根页号都是用一个字节表示的 text字段,创建表、索引、触发器或视图所使用的sql语句
接下来我们看一个具体的单元内容以及一个单元删除前后的页头以及单元头记录头的变化。
SQLite3数据库单元结构
记录大小 RowID Payload overflow