该字段是一个1到9个字节的变长整数,也就是记录内容部分的大小
该单元的记录在表中的行ID数,同样用1-9个字节的变长整数表示 记录内容部分 溢出页链表的第一个指针,没有溢出页的时候就没有这个域,给字段为4个字节SQLite3记录内容部分的结构是:
记录头 type Payload一个可变长整数,表示记录头加上type的个数 记录中每一个字段的类型描述,描述本身包含了字段的类型和长度(字节数) 记录真正的内容部分
type的类型具体有一下几种,计算字段的长度方法也附在表中:
type的值 表示的字段类型 长度(占据字节数)0 NULL 0
X(X∈{1,2,3,4}) 有符号整数 X
5 有符号整数 6
6 有符号整数 8
7 IEEE float 8
8 有符号整数 0
9 有符号整数 0
X(X∈{X>12,且X%2==0}) BLOB (X-12)/2
X(X∈{X>13,且X%2==1}) TEXT (X-13)/2
SQLite3数据库单眼数据删除前后变化情况
下面看一个具体的单元在删除前后的对比情况:
短信数据库的一条短信被删除前的单元数据信息为:
可以看到该单元的记录内容大小为0x36,也就是54个字节,该单元的记录在短信表的第5行,记录头的大小为0x1c,也就是28个字节,也就是说type的字节数为27个字节,第一个type值为0x00,也就是0;第二个type类型为0x02,是一个占据两个字节的有符号整数,与该符号相对应的值为0x06C2,下一个type值为0x17,是大于13的奇数,因此他表示一个长度为(23-13)/2=5的text文本,该字段对应的值为10086;一次类推,可以将整个字段所代表的含义解析出来,可以解析出来短信的内容为:text3。
下面来看一看删除该短信后,该单元以及单元所在页的页头改变:
与上面的数据进行对比我们可以发现,在该单元变成自由块之后只有前四个字节发生了变化,这是变化最少的情况,因为该数据比较少,单元头、RowID、记录头的大小都只用了一个字节就可以表示。
改变的前四个字节所代表的含义是:
前两个字节表示下一个自由块的起始地址;
后两个字节表示该自由块的大小,可以发现自由块的大小值比删除前单元的记录内容大小值多了2,也就是说自由块的大小值记录的是删除前整个单元的大小。
下面看看页头的变化:
删除前该页页头的情况是:
删除后该页的情况是:
可以看到删除后的第一个自由块起始地址不在是0,而是被删除的那天短信所在单元的起始地址0X09E7,该页的单元数从原来的7个变成了5个(变成5个是因为我在删除过程中手误删除了两条短信)。除此之外我们也能够发现,在记录该页各单元起始地址的区域结束后,后面的位置存储的数据是一致的,这也是一种部分覆盖的情况。
变长型整数
SQLite数据库中有很多的整数是设定为变长整数类型的,在这里也记录一下变长整数的规则。