May you do good and not evil.
May you find forgiveness for yourself and forgive others.
May you share freely, never taking more than you give.
體系結(jié)構(gòu)
?關(guān)于SQLite的體系結(jié)構(gòu),官網(wǎng)有詳細介紹,作為源碼剖析系列文章,本不應(yīng)該有如此多的廢話,而應(yīng)該直奔主題上代碼。但基于本人的經(jīng)驗,源碼閱讀前最好能夠先簡單實用過該軟件,清楚該軟件的體系結(jié)構(gòu),清晰的了解源代碼的分布,在開始閱讀源碼時才能更加順暢,So,推薦一讀SQLite體系結(jié)構(gòu)。
SQLite體系結(jié)構(gòu)
?就這張完美的圖片,簡單一講:SQLite數(shù)據(jù)庫將數(shù)據(jù)按照作者設(shè)計好的存儲結(jié)構(gòu)以文件方式存儲到文件系統(tǒng)上,用戶通過SQL語句實現(xiàn)數(shù)據(jù)的CURD,必要的步驟為:
- Interface接口接受用于輸入的CURD請求,請求嚴(yán)格遵守SQL標(biāo)準(zhǔn);
- 拿到SQL語句后,需要由分詞器Tokenizer把原有字符串分割成一個個標(biāo)識符(token),并把這些標(biāo)識符傳遞給解析器,Tokenizer是用手工編寫的;
- 解析器(Parser)拿到一個個Token后,進行語法分析。SQLite的語法分析器使用Lemon LALR(1)分析程序生成器來產(chǎn)生,代碼非常精簡,后續(xù)我們將認真分析;
- 語法分析一旦產(chǎn)生了規(guī)約(專業(yè)術(shù)語,后續(xù)文章詳細討論),就要調(diào)用代碼生成器(Code Generator),生成虛擬機代碼,以執(zhí)行SQL語句請求的工作。代碼生成器包含許多文件:attach.c, auth.c, build.c, delete.c, expr.c, insert.c,pragma.c, select.c, trigger.c, update.c, vacuum.c和where.c。這些文件涵蓋了大部分最重要、最有意義的事情。
- 代碼生成器生成的代碼由虛擬機(VDBE)來執(zhí)行,參考閱讀:SQLite虛擬機原理。虛擬機實現(xiàn)一個專為操作數(shù)據(jù)庫文件而設(shè)計的抽象計算引擎。它有一個存儲中間數(shù)據(jù)的存儲棧,每條指令包含一個操作碼和不超過三個額外的操作數(shù),它就像一個發(fā)動機,驅(qū)動著將用戶的意圖轉(zhuǎn)換成實際的動作,向數(shù)據(jù)庫文件拿或存用戶想要的數(shù)據(jù)。
- 虛擬機指令的動作,驅(qū)動了Page模塊向數(shù)據(jù)庫文件增刪改查數(shù)據(jù),而數(shù)據(jù)庫文件核心存儲結(jié)構(gòu)是B-樹,因此,其動作需要遵守B-樹結(jié)構(gòu)的指導(dǎo)進行。
- 數(shù)據(jù)庫文件被抽象出了一個個頁面(Page)存在硬盤中,每一頁都是B-樹(及其變種)的一個Node,操作系統(tǒng)提供標(biāo)準(zhǔn)文件操作接口供用戶訪問,SQLite通過內(nèi)部計算后有目的的向文件的特定位置進行讀取和寫入。
- 由此,完成了整個數(shù)據(jù)操作過程。
代碼結(jié)構(gòu)
?不多說,直接上表格:
所屬模塊 | 文件名稱 | 備注 |
---|---|---|
API | main.c | SQLite Library的大部分接口 |
legacy.c | sqlite3_exec的實現(xiàn) | |
table.c | the sqlite3_get_table() and sqlite3_free_table()的實現(xiàn),它們是sqlite3_exec的包裝 | |
preprare.c | 主要實現(xiàn)sqlite3_prepare() | |
分詞器部分(Tokenizer) | tokenize.c | 分詞器的實現(xiàn) |
語法分析器部分(Parser) | parser.c | 分析器的實現(xiàn),由Lemon自動生成 |
parser.h | 分析器內(nèi)部定義的關(guān)鍵字 | |
代碼生成器(Code Generator) | update.c | 處理UPDATTE語句 |
delete.c | 處理DELETE語句 | |
insert.c | 處理INSERT語句 | |
trigger.c | 處理TRIGGER語句 | |
attach.c | 處理ATTACHT 和DEATTACH語句 | |
select.c | 處理SELECT語句 | |
where.c | 處理WHERE語句 | |
vacuum.c | 處理VACUUM語句 | |
pragma.c | 處理PRAGMA命令 | |
expr.c | 處理SQL語句中的表達式 | |
auth.c | 主要實現(xiàn)sqlite3_set_authorizer() | |
analyze.c | 實現(xiàn)ANALYZE命令 | |
alter.c | 實現(xiàn)ALTER TABLE功能 | |
build.c | 處理以下語法:CREATE TABLE, DROP TABLE, CREATE INDEX,DROP INDEX,creating ID lists,BEGIN TRANSACTION,COMMIT,ROLLBACK | |
func.c | 實現(xiàn)SQL語句的函數(shù)語句 | |
date.c | 與日期和時間轉(zhuǎn)換有關(guān)的函數(shù) | |
虛擬機(Virtual Machine) | vdbeapi.c | 虛擬機提供上層模塊調(diào)用的API實現(xiàn)部分 |
vdbe.c | 虛擬機的主要實現(xiàn)部分 | |
vdbe.h | 定義了VDBE的接口,VdbeOp結(jié)構(gòu)體(代表一條指令) | |
vdbeaux.c | Vdbe.h的接口的實現(xiàn) | |
vdbeInt.h | Vdbe.c的私有頭文件,定義了VDBE常用的數(shù)據(jù)結(jié)構(gòu):Cursor——虛擬機中使用的游標(biāo), Mem——vdbe在內(nèi)部把所有的SQL值當(dāng)作一個Mem數(shù)據(jù)結(jié)構(gòu)來處理,Vdbe——虛擬機數(shù)據(jù)結(jié)構(gòu) | |
vdbemem.c | 操作”Mem”數(shù)據(jù)結(jié)構(gòu)的函數(shù) | |
vdbefifo.c | ||
B-Tree部分 | btree.h | 頭文件,定義了B-tree提供的操作接口 |
btree.c | B-Tree部分的主要實現(xiàn),并定義了以下數(shù)據(jù)結(jié)構(gòu):Btree——Btree handler,BtCursor——使用的游標(biāo), BtLock——鎖, BtShared——包含了一個打開的數(shù)據(jù)庫的所有信息,MemPage——文件在內(nèi)存存放在該數(shù)據(jù)結(jié)構(gòu)中,aCellInfo | |
OS Interface部分 | os.h | 定義了為上層模塊提供的操作函數(shù),并定義了以下數(shù)據(jù)結(jié)構(gòu):OsFile——描述一個文件;ioMethod——OsFile所支持的操作函數(shù)(對所有架構(gòu)都適用的OS Interface) |
os.c | 對IoMethod中的函數(shù)的包裝 | |
os_win.c | Windows平臺下的OS Interface | |
os_unix.c | Unix平臺下的OS Interface | |
os_os2.c | OS2平臺下的OS Interface | |
其它部分 | utf.c | 與UTF編碼有關(guān)的函數(shù) |
util.c | 一些實用函數(shù),比如:sqlite3Malloc(),sqlite3FreeX() | |
sqlite3.h | SQLite的頭文件,定義了提供給應(yīng)用使用的API和數(shù)據(jù)結(jié)構(gòu)。 | |
sqliteInt.h | 定義了SQLite內(nèi)部使用的接口和數(shù)據(jù)結(jié)構(gòu) | |
printf.c | 主要實現(xiàn)與printf有關(guān)的函數(shù) | |
random.c | 隨機數(shù)生成 | |
hash.c | SQLite使用的hash表 | |
hash.h | Hash 表頭文件 |
?有了對SQLite源碼從整體角度上的理解,我們源碼分析算是已經(jīng)開了一個頭了,后面的文章我們就將直接就某一塊代碼展開分析,感興趣的同學(xué)請持續(xù)關(guān)注!