本文件說明 SQLite 函式庫的架構。此處的資訊對想要了解或修改 SQLite 內部運作的人員很有用。
附近的圖表顯示 SQLite 的主要元件及其交互操作方式。下方的文字說明各種元件的角色。
SQLite 的運作方式是將 SQL 文字編譯成 位元組碼,然後使用虛擬機器執行該位元組碼。
sqlite3_prepare_v2() 及相關介面作為編譯器,將 SQL 文字轉換成位元組碼。 sqlite3_stmt 物件是單一位元組碼程式的容器,用來實作單一 SQL 陳述式。 sqlite3_step() 介面將位元組碼程式傳遞到虛擬機器,並執行程式,直到程式完成、形成要傳回的結果列、發生致命錯誤或 中斷 為止。
大部分的 C 語言介面 都可以在原始碼檔案 main.c、legacy.c 和 vdbeapi.c 中找到,儘管有些常式會分散在其他檔案中,以便存取具有檔案範圍的資料結構。sqlite3_get_table() 常式在 table.c 中實作。sqlite3_mprintf() 常式在 printf.c 中找到。sqlite3_complete() 介面在 complete.c 中。TCL 介面 由 tclsqlite.c 實作。
為了避免名稱衝突,SQLite 函式庫中的所有外部符號都以字首 sqlite3 開頭。那些供外部使用的符號(換句話說,那些構成 SQLite API 的符號)會加上底線,因此以 sqlite3_ 開頭。擴充功能 API 有時會在底線前加上擴充功能名稱;例如:sqlite3rbu_ 或 sqlite3session_。
當包含 SQL 陳述式的字串要被評估時,它會先傳送到分詞器。分詞器將 SQL 文字分成記號,並將這些記號一個一個傳遞給剖析器。分詞器是用手工編碼在檔案
請注意,在此設計中,分詞器會呼叫剖析器。熟悉 YACC 和 BISON 的人可能習慣反過來做這件事,也就是讓剖析器呼叫分詞器。不過,讓分詞器呼叫剖析器比較好,因為它可以變成執行緒安全的,而且執行速度更快。
剖析器根據其內容為令牌指派意義。SQLite 的剖析器使用 Lemon 剖析器產生器 產生。Lemon 與 YACC/BISON 執行相同的工作,但它使用較不易出錯的不同輸入語法。Lemon 也會產生一個可重新進入且執行緒安全的剖析器。Lemon 定義了非終端銷毀器的概念,以便在遇到語法錯誤時不會洩漏記憶體。驅動 Lemon 並定義 SQLite 所理解的 SQL 語言的語法檔案位於 parse.y。
由於 Lemon 是開發機器上通常找不到的程式,因此 Lemon 的完整原始碼(只有一個 C 檔案)包含在 SQLite 發行版的「tool」子目錄中。
After the parser assembles tokens into a parse tree, the code generator runs to analyze the parse tree and generate bytecode that performs the work of the SQL statement. The prepared statement object is a container for this bytecode. There are many files in the code generator, including: attach.c, auth.c, build.c, delete.c, expr.c, insert.c, pragma.c, select.c, trigger.c, update.c, vacuum.c, where.c, wherecode.c, and whereexpr.c. In these files is where most of the serious magic happens. expr.c handles code generation for expressions. where*.c handles code generation for WHERE clauses on SELECT, UPDATE and DELETE statements. The files attach.c, delete.c, insert.c, select.c, trigger.c update.c, and vacuum.c handle the code generation for SQL statements with the same names. (Each of these files calls routines in expr.c and where.c as necessary.) All other SQL statements are coded out of build.c. The auth.c file implements the functionality of sqlite3_set_authorizer().
程式碼產生器,尤其是 where*.c 和 select.c 中的邏輯,有時稱為 查詢規劃器。對於任何特定的 SQL 陳述式,可能會有數百、數千或數百萬種不同的演算法來計算答案。查詢規劃器是一種人工智慧,致力於從數百萬種選擇中選擇最佳演算法。
程式碼產生器建立的 位元組碼 程式由虛擬機器執行。
虛擬機器本身完全包含在單一來源檔案 vdbe.c 中。vdbe.h 標頭檔定義虛擬機器與 SQLite 函式庫的其他部分之間的介面,而 vdbeInt.h 定義虛擬機器本身的結構與介面。其他各種 vdbe*.c 檔案是虛擬機器的輔助程式。vdbeaux.c 檔案包含虛擬機器使用的公用程式,以及函式庫的其他部分用來建構 VM 程式所使用的介面模組。vdbeapi.c 檔案包含虛擬機器的外部介面,例如 sqlite3_bind_int() 和 sqlite3_step()。個別值(字串、整數、浮點數和 BLOB)儲存在稱為「Mem」的內部物件中,而此物件由 vdbemem.c 實作。
SQLite 使用呼叫回 C 語言常式的功能來實作 SQL 功能。甚至內建的 SQL 功能也是用這種方式實作。大部分內建的 SQL 功能(例如:abs()、count()、substr() 等)可以在 func.c 來源檔案中找到。日期和時間轉換功能可以在 date.c 中找到。有些功能,例如 coalesce() 和 typeof(),是由程式碼產生器直接以位元組碼實作。
SQLite 資料庫使用 btree.c 原始檔中找到的 B 樹實作維護在磁碟上。資料庫中的每個表格和每個索引使用個別的 B 樹。所有 B 樹都儲存在同一個磁碟檔案中。檔案格式 詳細資料穩定且定義良好,並保證未來相容。
B 樹子系統和 SQLite 函式庫的其他部分的介面由標頭檔 btree.h 定義。
B 樹模組以固定大小的頁面從磁碟中要求資訊。預設 page_size 為 4096 位元組,但可以在 512 到 65536 位元組之間的任何次方。頁面快取負責讀取、寫入和快取這些頁面。頁面快取也提供回滾和原子提交抽象,並負責鎖定資料庫檔案。B 樹驅動程式從頁面快取要求特定頁面,並在它想要修改頁面或提交或回滾變更時通知頁面快取。頁面快取處理所有複雜的細節,以確保要求快速、安全且有效率地處理。
主要的頁面快取實作在 pager.c 檔案中。WAL 模式 邏輯在個別的 wal.c 中。內存快取由 pcache.c 和 pcache1.c 檔案實作。頁面快取子系統和 SQLite 其他部分的介面由標頭檔 pager.h 定義。
為了在作業系統之間提供可攜性,SQLite 使用一個名為 VFS 的抽象物件。每個 VFS 提供方法來開啟、讀取、寫入和關閉磁碟上的檔案,以及其他特定於作業系統的任務,例如尋找目前時間,或取得隨機數來初始化內建的偽亂數產生器。SQLite 目前提供 VFS 給 unix(在 os_unix.c 檔案中)和 Windows(在 os_win.c 檔案中)。
記憶體配置、不分大小寫的字串比較常式、可攜式文字轉數字轉換常式,以及其他公用程式位於 util.c 中。解析器使用的符號表由 hash.c 中的雜湊表維護。utf.c 原始碼檔案包含 Unicode 轉換子常式。SQLite 在 printf.c 中有自己的 printf() 私有實作(含有一些延伸),並在 random.c 中有自己的偽亂數產生器 (PRNG)。
原始碼樹狀結構中「src/」資料夾中檔名以 test 開頭的檔案僅供測試,且未包含在標準的程式庫建置中。