對於大多數應用程式,建議使用 合併程式碼檔案 sqlite3.c 及其對應的標頭檔 sqlite3.h 來建置 SQLite。sqlite3.c 程式碼檔案應可在任何 Unix、Windows 系統上編譯並執行,無需任何變更或特殊編譯器選項。大多數應用程式可以簡單地將 sqlite3.c 檔案與組成應用程式的其他 C 程式碼檔案一起包含,將它們全部編譯在一起,並擁有運作良好且設定完善的 SQLite 版本。
大多數應用程式在 SQLite 的預設組態中運作良好,且無需任何特別的編譯時間組態。大多數開發人員應該可以完全忽略此文件,並從 合併中建置 SQLite,無需任何特殊知識,也無需採取任何特殊動作。
然而,高度調整且專門的應用程式可能想要或需要用更適合應用程式需求的替代實作來取代 SQLite 的部分內建系統介面。SQLite 設計為可在編譯時間輕鬆重新組態,以滿足個別專案的特定需求。SQLite 的編譯時間組態選項包括:
以替代實作取代內建互斥子系統。
完全停用所有互斥,以用於單執行緒應用程式。
重新組態記憶體配置子系統,以使用標準函式庫中的 malloc() 實作以外的記憶體配置器。
重新配置記憶體配置子系統,使其完全不呼叫 malloc(),而是使用在啟動時指定給 SQLite 的固定大小記憶體緩衝區來滿足所有記憶體要求。
以備用設計取代檔案系統的介面。換句話說,覆寫 SQLite 為了與磁碟對話而執行的所有系統呼叫,改用一組完全不同的系統呼叫。
覆寫其他作業系統介面,例如呼叫以取得 Zulu 時間或當地時間。
一般來說,SQLite 中有三個獨立的子系統可以在編譯時修改或覆寫。互斥子系統用於序列化對在執行緒間共用的 SQLite 資源的存取。記憶體配置子系統用於配置 SQLite 物件和資料庫快取所需的記憶體。最後,虛擬檔案系統子系統用於提供 SQLite 與底層作業系統,特別是檔案系統之間的可攜式介面。我們稱這三個子系統為 SQLite 的「介面」子系統。
我們強調,大多數應用程式都適用於 SQLite 介面子系統內建的預設實作。鼓勵開發人員盡可能使用預設內建實作,並在沒有任何特殊編譯時選項或參數的情況下建置 SQLite。但是,某些高度專業化的應用程式可能會受益於替換或修改其中一個或多個這些內建 SQLite 介面子系統。或者,如果 SQLite 用於 Unix(Linux 或 Mac OS X)、Windows(Win32 或 WinCE)或 OS/2 以外的作業系統,則 SQLite 內建的介面子系統都不會運作,而且應用程式需要提供適合目標平台的替代實作。
在多執行緒環境中,SQLite 使用互斥子來序列化對共用資源的存取。互斥子子系統僅適用於從多個執行緒存取 SQLite 的應用程式。對於單一執行緒應用程式,或僅從單一執行緒呼叫 SQLite 的應用程式,可以透過使用下列選項重新編譯來完全停用互斥子子系統
-DSQLITE_THREADSAFE=0
互斥鎖很便宜,但並非免費,因此在完全停用互斥鎖時,效能會更好。產生的程式庫佔用空間也會小一點。對於有意義的應用程式,建議在編譯時停用互斥鎖以進行最佳化。
在將 SQLite 用作共用程式庫時,應用程式可以使用 sqlite3_threadsafe() API 測試是否已停用互斥鎖。在執行階段與 SQLite 連結並從多個執行緒使用 SQLite 的應用程式,應檢查此 API 以確保不會意外連結到已停用其互斥鎖的 SQLite 程式庫版本。單執行緒應用程式當然會正確運作,無論 SQLite 是否設定為執行緒安全,但使用已停用互斥鎖的 SQLite 版本時,會快一點。
也可以使用 sqlite3_config() 介面在執行階段停用 SQLite 互斥鎖。若要完全停用所有互斥鎖,應用程式可以呼叫
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
在執行階段停用互斥鎖不如在編譯階段停用來得有效,因為 SQLite 仍必須測試布林變數,才能在可能需要互斥鎖的每個點查看互斥鎖是否已啟用或停用。但停用執行階段的互斥鎖仍有效能優勢。
對於在執行緒管理方面很小心的多執行緒應用程式,SQLite 支援一種替代執行階段設定,介於不使用任何互斥鎖和預設情況(對所有可見的項目進行互斥鎖)之間。這種中間互斥鎖比對方式可以如下建立
sqlite3_config(SQLITE_CONFIG_MULTITHREAD); sqlite3_config(SQLITE_CONFIG_MEMSTATUS, 0);
這裡有兩個獨立的組態變更,它們可以一起或分開使用。SQLITE_CONFIG_MULTITHREAD 設定會停用序列化的存取權限,以資料庫連線物件和準備好的陳述式物件。有了這個設定,應用程式就能自由地從多個執行緒使用 SQLite,但它必須確保沒有兩個執行緒嘗試同時存取相同的資料庫連線或任何與同一個資料庫連線相關聯的準備好的陳述式。兩個執行緒可以同時使用 SQLite,但它們必須使用獨立的資料庫連線。第二個SQLITE_CONFIG_MEMSTATUS設定會停用 SQLite 中追蹤所有未完成記憶體配置請求總大小的機制。這會省略對sqlite3_malloc()和sqlite3_free()的每個呼叫進行互斥鎖的需要,這會節省大量的互斥鎖操作。但停用記憶體統計機制的後果是sqlite3_memory_used()、sqlite3_memory_highwater()和sqlite3_soft_heap_limit64()介面會停止運作。
SQLite 在 Unix 上使用 pthreads 作為其互斥鎖實作,而 SQLite 需要一個遞迴互斥鎖。大多數現代的 pthread 實作都支援遞迴互斥鎖,但並非所有實作都支援。對於不支援遞迴互斥鎖的系統,建議應用程式僅在單執行緒模式下操作。如果這不可行,SQLite 提供了一個替代的遞迴互斥鎖實作,建構在 pthreads 的標準「快速」互斥鎖之上。只要 pthread_equal() 是原子的,而且處理器具有相干資料快取,這個替代實作就應該能正確運作。替代的遞迴互斥鎖實作是由下列編譯器命令列開關啟用的
-DSQLITE_HOMEGROWN_RECURSIVE_MUTEX=1
當將 SQLite 移植到新的作業系統時,通常需要用新的作業系統的 mutex 原語建立的替代方案,完全取代內建的 mutex 子系統。這是透過編譯 SQLite,加上下列選項來完成的
-DSQLITE_MUTEX_APPDEF=1
當 SQLite 是用 SQLITE_MUTEX_APPDEF=1 選項編譯時,它會完全省略其 mutex 原語函數 的實作。但 SQLite 函式庫仍會在必要時嘗試呼叫這些函數,因此應用程式本身必須實作 mutex 原語函數,並將它們連結到 SQLite。
預設情況下,SQLite 會從標準函式庫的 malloc()/free() 實作取得物件和快取所需的記憶體。目前也正在進行實驗性的記憶體配置器的工作,這些配置器會從應用程式啟動時傳遞給 SQLite 的單一固定記憶體緩衝區滿足所有記憶體要求。這些實驗性記憶體配置器的其他資訊將在本文檔的未來版本中提供。
SQLite 支援應用程式在執行階段指定替代記憶體配置器的功能,方法是填入 sqlite3_mem_methods 物件的執行個體,其中包含替代實作的常式,然後使用 sqlite3_config() 介面註冊新的替代實作。例如
sqlite3_config(SQLITE_CONFIG_MALLOC, &my_malloc_implementation);
SQLite 會複製 sqlite3_mem_methods 物件的內容,因此可以在 sqlite3_config() 呼叫傳回後修改物件。
自 版本 3.5.0(2007-09-04)以來,SQLite 已支援稱為 虛擬檔案系統 或「VFS」的介面。此物件名稱有點誤導,因為它實際上是整個底層作業系統的介面,不只是檔案系統。
VFS 介面的其中一項有趣功能是 SQLite 可以同時支援多個 VFS。每個 資料庫連線 都必須在使用 sqlite3_open_v2() 首次開啟連線時,為其使用選擇單一 VFS。但是,如果一個程序包含多個 資料庫連線,每個連線都可以選擇不同的 VFS。VFS 可以使用 sqlite3_vfs_register() 介面在執行階段新增。
SQLite 在 Unix、Windows 和 OS/2 上的預設建置包含適用於目標平台的 VFS。SQLite 在其他作業系統上的建置預設不包含 VFS,但應用程式可以在執行階段註冊一個或多個 VFS。
要將 SQLite 移植到新的作業系統(預設不支援的作業系統),應用程式必須提供...
所有這些都可以在單一輔助 C 程式碼檔案中提供,然後與現有的「sqlite3.c」程式碼檔案連結,以產生適用於目標作業系統的可運作 SQLite 建置。除了替代的 mutex 和記憶體配置子系統以及新的 VFS 之外,輔助 C 程式碼檔案應包含以下兩個常式的實作
「sqlite3.c」程式碼檔案包含 VFS 的預設實作,以及 sqlite3_initialize() 和 sqlite3_shutdown() 函式,這些函式適用於 Unix、Windows 和 OS/2。若要防止在編譯 sqlite3.c 時載入其中一個預設元件,必須加入下列編譯時期選項
-DSQLITE_OS_OTHER=1
SQLite 核心會在早期呼叫 sqlite3_initialize()。輔助的 C 程式碼檔案可以包含 sqlite3_initialize() 的實作,以註冊適當的 VFS,並且可能初始化替代的 mutex 系統(如果需要 mutex)或執行任何必要的記憶體配置子系統初始化。SQLite 核心從不呼叫 sqlite3_shutdown(),但它是官方 SQLite API 的一部分,在使用 -DSQLITE_OS_OTHER=1 編譯時,否則不會提供它,因此輔助的 C 程式碼檔案可能應該提供它以求完整性。