此分析稱為簡易版,因?yàn)楹竺孢€計(jì)劃分析一個(gè)更復(fù)雜的數(shù)據(jù)庫文件,以深入理解SQLite數(shù)據(jù)庫B樹實(shí)現(xiàn)的結(jié)構(gòu),從簡易的開始不失為一種好的學(xué)習(xí)方法,這里的簡易版本文件是指大小為2K字節(jié),即每個(gè)B樹頁1K字節(jié),共兩個(gè)B樹頁,補(bǔ)充說明一下,這里的B樹頁就是指經(jīng)典數(shù)據(jù)結(jié)構(gòu)書上所講的B樹節(jié)點(diǎn),在這里稱為頁是因?yàn)镾QLite在實(shí)現(xiàn)B樹時(shí)就是使用頁page的概念來組織的。
創(chuàng)建方法如下:
CREATE TABLE tbl1(one varchar(10),two varchar(10));
INSERT INTO "tbl1" VALUES('first', 'xxx');
INSERT INTO "tbl1" VALUES('second', 'yyy');
然后退出,用UltraEdit打開這個(gè)數(shù)據(jù)庫文件:
00000000h: 53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00 ; SQLite format 3.
00000010h: 04 00 01 01 00 40 20 20 00 00 00 07 00 00 00 00 ; .....@? ........
00000020h: 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 01 ; ................
00000030h: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ; ................
00000040h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000050h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000060h: 00 00 00 00 0D 00 00 00 01 03 B8 00 03 B8 00 00 ; ..........?.?.
00000070h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
這中間部分全部都是零。省去!
000003a0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
000003b0h: 00 00 00 00 00 00 00 00 46 01 06 17 15 15 01 71 ; ........F......q
000003c0h: 74 61 62 6C 65 74 62 6C 31 74 62 6C 31 02 43 52 ; tabletbl1tbl1.CR
000003d0h: 45 41 54 45 20 54 41 42 4C 45 20 74 62 6C 31 28 ; EATE TABLE tbl1(
000003e0h: 6F 6E 65 20 76 61 72 63 68 61 72 28 31 30 29 2C ; one varchar(10),
000003f0h: 74 77 6F 20 76 61 72 63 68 61 72 28 31 30 29 29 ; two varchar(10))
???? 這是第一個(gè)B樹頁,這個(gè)B樹頁里存放了表sqlite_master的信息,這就是SQLite數(shù)據(jù)庫的系統(tǒng)表了。
下面分析一下這些二進(jìn)制的具體涵義,SQLite統(tǒng)一采用大端法來表示數(shù)據(jù),不同與一般intel機(jī)器的小端法了:
偏移地址?? 大小??? 涵義
?0????????? 16???? "SQLite format 3\000"
16?????????? 2???? 400H=1024個(gè)字節(jié),每個(gè)頁面的字節(jié)數(shù)?
18?????????? 2???? 0101H表示版本號(hào)而已
20?????????? 1???? 每頁末端的未用空間,這里為零表示數(shù)據(jù)都是從每頁最后一個(gè)字節(jié)開始存放
21?????????? 1???? 最大負(fù)載分片數(shù),類似與IP分片,一頁存不下,要分片
22?????????? 1???? 最小負(fù)載分片數(shù)
23?????????? 1???? 最小葉子負(fù)載分片數(shù)
24?????????? 4???? 文件修改計(jì)數(shù),用于實(shí)現(xiàn)并行訪問
28?????????? 4???? 保留未用
32?????????? 4???? 第一個(gè)freelist頁
36?????????? 4???? 文件中的freelist頁數(shù)
40????????? 60???? 這里未用
上面的這一百個(gè)字節(jié)稱為數(shù)據(jù)庫文件的文件頭,這個(gè)文件頭只有第一個(gè)B樹頁才有,后面的每一個(gè)B樹頁都沒有這個(gè)結(jié)構(gòu),后面每一頁結(jié)構(gòu)都相同:
依次為:B樹頁頭結(jié)構(gòu),B樹指針結(jié)構(gòu),未用空間,B樹實(shí)際數(shù)據(jù)負(fù)載。
這里和經(jīng)典數(shù)據(jù)結(jié)構(gòu)書上的B樹結(jié)構(gòu)有些出入,這里的目的是實(shí)際應(yīng)用方便,而書上的結(jié)構(gòu)目的是解釋清楚B樹的原理。所以有些不同:
一般書上講的一個(gè)B樹頁的結(jié)構(gòu)為:指針,數(shù)據(jù),指針,數(shù)據(jù),指針,數(shù)據(jù),...,指針
而SQLite組織為:指針,指針,指針,...,指針,數(shù)據(jù),數(shù)據(jù),...數(shù)據(jù)。
第一個(gè)頁面中從00000060h行第五個(gè)字節(jié)開始就表示B樹頁頭結(jié)構(gòu)了:
偏移地址?? 大小??? 涵義
0?????????? 1????? 0Dh=1101b各位意義為1: intkey, 2: zerodata, 4: leafdata, 8: leaf
1?????????? 2????? 第一個(gè)空閑塊的字節(jié)偏移量,這里為0
3?????????? 2????? 01,這個(gè)B樹頁存放的記錄數(shù)為1個(gè),即系統(tǒng)表中只存放了一條記錄,因?yàn)橹粍?chuàng)建了一個(gè)表tbl1
5?????????? 2????? 負(fù)載區(qū)首地址,03B8,往下看到000003b0h行那個(gè)46就是負(fù)載區(qū)的開始了
7?????????? 1????? 分片數(shù),這里數(shù)據(jù)少,不考慮,所以為0
到0000006Bh偏移處B數(shù)頭結(jié)束了,接下來的就是B數(shù)指針結(jié)構(gòu)了,此處只有一項(xiàng),只有一個(gè)指針03B8h處。
從000003B8h偏移到結(jié)束都是sqlite_master表的實(shí)際數(shù)據(jù)了。當(dāng)然這些數(shù)據(jù)也是有結(jié)構(gòu)的。46h表示這條記錄有70個(gè)字節(jié),除去其本身46,和后面的01是索引外,整個(gè)記錄剛好是70個(gè)字節(jié),01索引后面都是payload負(fù)載數(shù)據(jù)了。
如法炮制,下面列出第二個(gè)B樹頁:
00000400h: 0D 00 00 00 02 03 E5 00 03 F3 03 E5 00 00 00 00 ; ......?.??...
00000410h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
這中間部分全部為零。省去!
000007d0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
000007e0h: 00 00 00 00 00 0C 02 03 19 13 73 65 63 6F 6E 64 ; ..........second
000007f0h: 79 79 79 0B 01 03 17 13 66 69 72 73 74 78 78 78 ; yyy.....firstxxx
由于不是第一頁,所以不存在文件頭的100個(gè)字節(jié)了,一開始就是B樹頁頭結(jié)構(gòu)了,這里有兩個(gè)指針03F3和03E5,其它的和上面一樣。整個(gè)數(shù)據(jù)庫管理系統(tǒng)就是準(zhǔn)確無誤地對(duì)這個(gè)文件進(jìn)行管理。
進(jìn)一步的工作:只有數(shù)據(jù)多了,才能看出B樹組織的好處:查找,刪除,增加的快速!把這個(gè)文件變大再分析!