下圖是一個體繫結構圖,顯示了SQLite的主要組件以及各組件之間是如何相互關聯的。html
在內部,SQLite由如下幾個組件組成:內核、SQL編譯器、後端以及附件。SQLite經過利用虛擬機和虛擬數據庫引擎(VDBE),使調試、修改和擴展SQLite的內核變得更加方便。全部SQL語句都被編譯成易讀的、能夠在SQLite虛擬機中執行的程序集。SQLite支持大小高達2 TB的數據庫,每一個數據庫徹底存儲在單個磁盤文件中。這些磁盤文件能夠在不一樣字節順序的計算機之間移動。這些數據以B+樹(B+tree)數據結構的形式存儲在磁盤上。SQLite根據該文件系統得到其數據庫權限。sql
一、公共接口(Interface)
SQLite庫的大部分公共接口由main.c, legacy.c和vdbeapi.c源文件中的函數來實現,這些函數依賴於分散在其餘文件中的一些程序,由於在這些文件中它們能夠訪問有文件做用域的數據結構。sqlite3_get_table()例程在table.c中實現,sqlite3_mprintf()可在printf.c中找到,sqlite3_complete()則位於tokenize.c中。Tcl接口在tclsqlite.c中實現。SQLite的C接口信息可參考http://sqlite.org/capi3ref.html。
爲了不和其餘軟件的名字衝突,SQLite庫的全部外部符號都以sqlite3爲前綴,這些被用來作外部使用的符號(換句話說,這些符號用來造成SQLite的API)是以sqlite3_開頭來命名的。數據庫
二、詞法分析器(Tokenizer)
當執行一個包含SQL語句的字符串時,接口程序要把這個字符串傳遞給tokenizer。Tokenizer的任務是把原有字符串分割成一個個標識符(token),並把這些標識符傳遞給解析器。Tokenizer是用手工編寫的,在C文件tokenize.c中。
在這個設計中須要注意的一點是,tokenizer調用parser。熟悉YACC和BISON的人們也許會習慣於用parser調用tokenizer。SQLite的做者已經嘗試了這兩種方法,並發現用tokenizer調用parser會使程序運行的更好。YACC會使程序更滯後一些。後端
三、語法分析器(Parser)api
語法分析器的工做是在指定的上下文中賦予標識符具體的含義。SQLite的語法分析器使用Lemon LALR(1)分析程序生成器來產生,Lemon作的工做與YACC/BISON相同,但它使用不一樣的輸入句法,這種句法更不易出錯。Lemon還產生可重入的而且線程安全的語法分析器。Lemon定義了非終結析構器的概念,當遇到語法錯誤時它不會泄露內存。驅動Lemon的源文件可在parse.y中找到。
由於lemon是一個在開發機器上不常見的程序,因此lemon的源代碼(只是一個C文件)被放在SQLite的"tool"子目錄下。 lemon的文檔放在"doc"子目錄下。緩存
四、代碼生成器(Code Generator)安全
語法分析器在把標識符組裝成完整的SQL語句後,就調用代碼生成器產生虛擬機代碼,以執行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。這些文件涵蓋了大部分最重要、最有意義的事情。expr.c處理SQL中表達式的代碼生成。where.c處理SELECT、UPDATE和DELETE語句中WHERE子句的代碼生成。文件attach.c, delete.c, insert.c, select.c, trigger.c, update.c和vacuum.c處理同名SQL語句的代碼生成(這些文件在必要時都調用expr.c和where.c中的例程)。全部其餘SQL語句的代碼由build.c生成。文件auth.c實現sqlite3_set_authorizer()的功能。數據結構
五、虛擬機(Virtual Machine)架構
代碼生成器生成的代碼由虛擬機來執行。關於虛擬機更詳細的信息可參考http://sqlite.org/opcode.html。總的來講,虛擬機實現一個專爲操做數據庫文件而設計的抽象計算引擎。它有一個存儲中間數據的存儲棧,每條指令包含一個操做碼和不超過三個額外的操做數。
虛擬機自己被完整地包含在一個單獨的文件vdbe.c中,它也有本身的頭文件,其中vdbe.h定義虛擬機與SQLite庫其餘部分之間的接口,vdbeInt.h定義虛擬機私有的數據結構。文件vdbeaux.c包含被虛擬機使用的一些工具,和被庫的其餘部分用來構建VM程序的一些接口模塊。文件vdbeapi.c包含虛擬機的外部接口,例如sqlite3_bind_...族的函數。單獨的值(字符串、整數、浮點數、BLOB對象)被存儲在一個叫Mem的內部對象中,在vdbemem.c中可找到它的實現。
SQLite使用回調風格的C語言程序來實現SQL函數,每一個內建的SQL函數都用這種方式來實現。大多數內建的SQL函數(例如coalesce(), count(), substr(), 等等)可在func.c中找到。日期和時間轉換函數可在date.c中找到。併發
六、B-樹(B-Tree)
一個SQLite數據庫使用B-樹的形式存儲在磁盤上,B-樹的實現位於源文件btree.c中。數據庫中的每一個表和索引使用一棵單獨的B-樹,全部的B-樹存放在同一個磁盤文件中。文件格式的細節被記錄在btree.c開頭的備註裏。B-樹子系統的接口在頭文件btree.h中定義。
七、頁面高速緩存(Page Cache)
B-樹模塊以固定大小的數據塊形式從磁盤上請求信息,默認的塊大小是1024個字節,可是能夠在512和65536個字節之間變化。頁面高速緩存負責讀、寫和緩存這些數據塊。頁面高速緩存還提供回滾和原子提交的抽象,而且管理數據文件的鎖定。B-樹驅動模塊從頁面高速緩存中請求特定的頁,當它想修改頁面、想提交或回滾當前修改時,它也會通知頁面高速緩存。頁面高速緩存處理全部麻煩的細節,以確保請求可以快速、安全而有效地被處理。
頁面高速緩存的代碼實現被包含在單一的C源文件pager.c中。頁面高速緩存子系統的接口在頭文件pager.h中定義。
八、OS接口
爲了在POSIX和Win32操做系統之間提供移植性,SQLite使用一個抽象層來提供操做系統接口。OS抽象層的接口在os.h中定義,每種支持的操做系統有各自的實現:Unix使用os_unix.c,Windows使用os_win.c,等等。每一個特定操做系統的實現一般都有本身的頭文件,如os_unix.h, os_win.h等。
九、實用工具(Utilities)
內存分配和字符串比較函數位於util.c中。語法分析器使用的符號表用Hash表來維護,其實現位於hash.c中。源文件utf.c包含Unicode轉換子程序。SQLite有本身的printf()實現(帶一些擴展功能),在printf.c中,還有本身的隨機數生成器,在random.c中。
十、測試代碼(Test Code)
若是你計算迴歸測試腳本,超過一半的SQLite代碼將被測試。主要代碼文件中有許多assert()語句。另外,源文件test1.c經過test5.c和md5.c實現只用於測試目的的一些擴展。os_test.c後端接口用來模擬斷電,以驗證頁面高速緩存的崩潰恢復機制。
文件名稱 | 大小byte | 備註 | |
API | main.c | 35414 | SQLite Library的大部分接口 |
legacy.c | 3734 | sqlite3_exec的實現 | |
table.c | 5464 | the sqlite3_get_table() and sqlite3_free_table()的實現,它們是sqlite3_exec的包裝 | |
preprare.c | 17983 | 主要實現sqlite3_prepare() | |
分詞器部分(Tokenizer) | tokenize.c | 14495 | 分詞器的實現 |
語法分析器部分(Parser) | parser.c | 116917 | 分析器的實現,由Lemon實現 |
parser.h | 6847 | 分析器內部定義的關鍵字 | |
代碼生成器(Code Generator) | update.c | 23878 | 處理UPDATTE語句 |
delete.c | 21978 | 處理DELETE語句 | |
insert.c | 62026 | 處理INSERT語句 | |
trigger.c | 29065 | 處理TRIGGER語句 | |
attach.c | 15941 | 處理ATTACHT 和DEATTACH語句 | |
select.c | 112084 | 處理SELECT語句 | |
where.c | 75826 | 處理WHERE語句 | |
vacuum.c | 11005 | 處理VACUUM語句 | |
pragma.c | 34289 | 處理PRAGMA命令 | |
expr.c | 73963 | 處理SQL語句中的表達式 | |
auth.c | 7496 | 主要實現sqlite3_set_authorizer() | |
analyze.c | 13149 | 實現ANALYZE命令 | |
alter.c | 18414 | 實現ALTER TABLE功能 | |
build.c | 104052 | 處理如下語法:CREATE TABLE, DROP TABLE, CREATE INDEX,DROP INDEX,creating ID lists,BEGIN TRANSACTION,COMMIT,ROLLBACK | |
func.c | 34335 | 實現SQL語句的函數語句 | |
date.c | 24031 | 與日期和時間轉換有關的函數 | |
虛擬機(Virtual Machine) | vdbeapi.c | 23300 | 虛擬機提供上層模塊調用的API實現部分 |
vdbe.c | 143552 | 虛擬機的主要實現部分 | |
vdbe.h | 5309 | 定義了VDBE的接口,VdbeOp結構體(表明一條指令) | |
vdbeaux.c | 58741 | Vdbe.h的接口的實現 | |
vdbeInt.h | 17595 | Vdbe.c的私有頭文件,定義了VDBE經常使用的數據結構:Cursor——虛擬機中使用的遊標, Mem——vdbe在內部把全部的SQL值看成一個Mem數據結構來處理,Vdbe——虛擬機數據結構 | |
vdbemem.c | 26375 | 操做」Mem」數據結構的函數 | |
vdbefifo.c | 2927 | ||
B-Tree部分 | btree.h | 5260 | 頭文件,定義了B-tree提供的操做接口 |
btree.c | 215570 | B-Tree部分的主要實現,並定義瞭如下數據結構:Btree——Btree handler,BtCursor——使用的遊標, BtLock——鎖, BtShared——包含了一個打開的數據庫的全部信息,MemPage——文件在內存存放在該數據結構中,aCellInfo | |
OS Interface部分 | os.h | 18355 | 定義了爲上層模塊提供的操做函數,並定義瞭如下數據結構: |
OsFile——描述一個文件 | |||
IoMethod——OsFile所支持的操做函數(對全部架構都適用的OS Interface) | |||
os.c | 2866 | 對IoMethod中的函數的包裝 | |
os_win.c | 42975 | Windows平臺下的OS Interface | |
os_unix.c | 60831 | Unix平臺下的OS Interface | |
os_os2.c | 28451 | OS2平臺下的OS Interface | |
其它部分 | utf.c | 20891 | 與UTF編碼有關的函數 |
util.c | 43575 | 一些實用函數,好比: | |
sqlite3Malloc(),sqlite3FreeX() | |||
sqlite3.h | 63873 | SQLite的頭文件,定義了提供給應用使用的API和數據結構。 | |
sqliteInt.h | 78886 | 定義了SQLite內部使用的接口和數據結構 | |
printf.c | 29556 | 主要實現與printf有關的函數 | |
random.c | 3078 | 隨機數生成 | |
hash.c | 11896 | SQLite使用的hash表 | |
hash.h | 4033 | Hash 表頭文件 |