SQLite 檔案詳解:結構、應用案例與關鍵限制

SQLite 檔案是單一的磁碟檔案,保存了整個關聯式資料庫——包含資料表、索引和綱要。SQLite 的官方文件將其稱為「主資料庫檔案」,並指出「SQLite 資料庫的完整狀態通常包含」在其中。在該句子中,「通常」這個詞扮演了非常關鍵的角色。
如果您曾經拿到過 .db、.sqlite 或 .sqlite3 檔案,並懷疑自己是否收到了完整的資料,那麼這就是您需要深入了解的格式。
SQLite 檔案究竟是什麼
SQLite 自稱為「一個行程內(in-process)的函式庫,實現了自包含、無伺服器、零設定、交易式的 SQL 資料庫引擎。」同一個頁面也指出,SQLite「沒有獨立的伺服器行程」。應用程式會連結該函式庫並讀取檔案。
這帶來了兩個結果。首先,資料庫是以單一產物的方式傳輸,這也是為什麼這麼多應用程式都以這種方式交付資料。其次,該格式必須極其穩定,因為這些檔案的壽命比寫入它們的軟體還要長。SQLite 將「穩定、持久的檔案格式」列為其核心特色之一。它還指出,其程式碼屬於公有領域,「可免費用於任何目的,無論是商業還是私人用途。」
其規模很容易被低估。SQLite 自己的介紹頁面指出,它「是世界上部署最廣泛的資料庫,應用案例多到無法估量。」
檔案裡面有什麼
100 位元組的標頭
開頭的幾個位元組用於識別格式。在偏移量 0 處,檔案包含一個 16 位元組的標頭字串:SQLite format 3\000。無論副檔名是什麼,工具都是透過這個特徵標記來識別該檔案。
下一個欄位比看起來更重要。在偏移量 16 處是一個 2 位元組的整數,保存著「以位元組為單位的資料庫分頁大小」。官方文件指出,它「必須是 512 到 32768 之間(含)的 2 的冪次方,或者是代表分頁大小為 65536 的值 1」。標頭中的所有多位元組欄位都以最高有效位元組(most significant byte)在前的順序儲存。
接下來在偏移量 18 和 19 處還有兩個位元組:檔案格式的寫入版本和讀取版本。官方文件指出,該值「1 代表舊版;2 代表 WAL」。
是分頁,而不是資料列
在標頭下方,該檔案是一疊固定大小的分頁。規格說明書中明確指出:「主資料庫檔案由一個或多個分頁組成。分頁的大小是 512 到 65536 之間(含)的 2 的冪次方。同一個資料庫內的所有分頁大小皆相同。」
分頁從 1 開始編號,最大分頁編號為 4,294,967,294。資料表和索引以 B-tree 結構存在於這些分頁中,這就是為什麼用文字編輯器打開時幾乎看不到任何有用內容的原因。
沒人提及的附屬檔案
這是最容易讓人出錯的地方。官方文件指出,完整狀態「通常」在一個檔案中。接著它指出了例外情況。在交易過程中,SQLite「會將額外資訊儲存在名為『回復日誌(rollback journal)』的第二個檔案中」。在 WAL 模式下,這第二個檔案則是預寫式日誌(write-ahead log)。
因此,在應用程式寫入過程中複製的檔案,可能會遺失仍存在於附屬檔案中的已提交資料。如果同事只給了您一個 .db 檔案而沒有其他東西,且資料看起來有些過期,這就是首先需要檢查的事情。
如何開啟 SQLite 檔案
有三種途徑,選擇哪一種取決於您接下來打算做什麼。
使用檢視器讀取。 桌面端和網頁瀏覽器型的 SQLite 檢視器可以開啟檔案、列出資料表,並讓您點選瀏覽各個資料列。這是回答「這裡面到底有什麼」最快的方法,通常對於初步查看已經足夠。
使用命令列或函式庫進行查詢。 sqlite3 終端機以及 Python、Node 和大多數其他語言中的標準函式庫綁定可以直接讀取該格式。當您已經知道綱要並想要獲取特定數值時,這是一條適合的途徑。
匯出資料表並在其他地方進行分析。 將資料表傾印(dump)為 CSV,然後匯入您團隊已在使用的任何工具中。這樣做會失去資料表之間的關聯性,而這正是該格式原本所保護的核心。如果可以的話,請匯出合併(join)後的結果,而不是原始資料表。
為什麼工具可能會顯示該檔案不是資料庫
規格說明書解釋了這一點。每個有效的檔案都以 16 位元組的標頭字串 SQLite format 3\000 開頭。如果讀取器開啟檔案後,在偏移量 0 處沒有找到該特徵標記,則說明傳入的並非 SQLite 資料庫。
大多數情況可以歸結為三個常見原因:檔案傳輸不完整,因此雖然有標頭,但其餘部分被截斷了;檔案被應用程式加密或封裝,因此開頭的位元組是其他內容;或者副檔名具有誤導性,您實際收到的是某個熱心人士重新命名過的純文字匯出檔。
SQLite 檔案最大可以到多大
比這個問題通常暗示的還要大。SQLite 的限制說明頁面指出,資料庫檔案的最大容量為 4,294,967,294 個分頁。在最大分頁大小 65,536 位元組下,最大資料庫容量約為 281 TB。
該頁面對於這個數字表現得非常坦誠。它指出,這個上限「尚未經過測試,因為開發人員沒有可以達到此限制的硬體設備。」
資料列的數量也受到同樣的限制。理論上的最大值是單一資料表中包含 2^64 個資料列。官方文件指出,這個限制「是無法達到的,因為會先達到 281 TB 的最大資料庫容量限制。」
對於實際工作而言,有用的啟示與限制庫正好相反。如果有人給您一個 .db 檔案並警告它很大,該格式幾乎絕對不會成為限制您的瓶頸。建立檔案時選擇的分頁大小,以及它是否包含索引,對使用體驗的影響遠大於任何文件上記載的上限。
您會在哪些地方遇到 SQLite 檔案
- 應用程式匯出。 桌面和行動應用程式通常會將歷史記錄、設定和訊息日誌儲存在您可以複製出來的 SQLite 檔案中。
- 分析資料交付。 工程師會將快照封裝為單一檔案交付,而不是直接授予資料庫存取權限。
- 裝置與遙測。 嵌入式系統會寫入本機,因為沒有可以通訊的伺服器。
- 封存。 該格式的長期穩定性使其成為需要多年保持可讀性的資料集的常見選擇。
- 瀏覽器與工具內部機制。 許多本機工具都以這種方式保存狀態,這也是為什麼該副檔名經常出現在支援工單中的原因。
WAL 和日誌檔案的作用是什麼
您可能在複製 .db 檔案時,發現旁邊還有一個 -wal 或 -journal 檔案。這些就是規格說明書中所描述的附屬檔案,而刪除它們正是人們遺失資料的原因。
回復日誌(rollback journal)是較舊的機制。在修改分頁之前,SQLite 會將該分頁的原始版本寫入日誌中。如果寫入中斷,則可以將原始版本還原,這就是交易能在當機時倖免於難的原因。
預寫式日誌(write-ahead log)顛倒了這種安排。變更會先寫入日誌中,稍後再更新主檔案。標頭會標記資料庫處於哪種模式。偏移量 18 處的檔案格式寫入版本為「1 代表舊版;2 代表 WAL」。
實用規則直接源自於關於完整狀態的那句話。假設資料庫處於 WAL 模式,而有人只給了您主檔案。最近提交的變更可能仍然留在您未收到的日誌中。
因此,當您拿到資料庫檔案時,請詢問兩個問題:複製檔案時應用程式是否已正常關閉?是否有其他附帶檔案?這兩個問題的答案通常都是「是」,而一旦答案為「否」,資料庫中的數據就可能與實際生產環境中的數據產生出入。
SQLite 檔案 vs CSV vs Parquet
| SQLite 檔案 | CSV | Parquet | |
|---|---|---|---|
| 結構 | 多個資料表,單一檔案 | 單一資料表,單一檔案 | 單一資料表,單一檔案或資料夾 |
| 型態 | 與資料一同儲存 | 由讀取器推斷 | 與資料一同儲存 |
| 關聯性 | 透過鍵和索引保留 | 遺失 | 遺失 |
| 人類可讀 | 否 | 是 | 否 |
| 專為查詢而寫入 | 是,使用 SQL | 否 | 是,由分析引擎查詢 |
| 常見失敗原因 | 遺失日誌或 WAL 附屬檔案 | 型態與分隔符號猜測錯誤 | 工具鏈支援問題 |
如果您經常使用這些格式,我們關於 Parquet 檔案 和 TSV 檔案 的說明文章也為這兩者提供了相同的基礎知識。
為什麼團隊會選擇此格式
無需運行任何服務。 因為 SQLite「沒有獨立的伺服器行程」,所以交付資料只需複製檔案,而不需要申請伺服器資源。
型態在傳輸後依然保留。 日期欄位在接收端仍是日期。任何曾看過 CSV 讀取器將識別碼轉換為科學記號的人,都能理解這項特性的價值。
關聯性也得以保留。 多個相關的資料表保存在同一個產物中,因此使資料具有意義的合併(join)操作依然可用。
內建持久性設計。 SQLite 將「即使在斷電後」也能保證交易安全列為其核心特色,這也是為什麼如此多的嵌入式軟體都依賴它的原因。
值得了解的限制
單一檔案,一次只能有一個寫入者。 該引擎是嵌入式的,而非透過伺服器提供服務,因此其並行模型與用戶端-伺服器(client-server)資料庫不同。這是一種設計選擇,而非缺陷,但它決定了該檔案適合用於哪些場景。
分頁大小在建立時即固定。 資料庫中的每個分頁大小都相同,且該大小記錄在標頭中。您只需在建立時選擇一次。
再次強調附屬檔案規則。 任何僅擷取主檔案的複製、備份或上傳程序,都可能會遺失日誌或預寫式日誌中的任何內容。
不透明性。 SQLite 檔案無法像 CSV 那樣快速瀏覽。讀取它需要工具,而這正是阻礙許多分析工作的摩擦力所在。
如何從 SQLite 檔案中獲取答案
傳統的途徑是安裝用戶端、開啟檔案、了解綱要,然後開始撰寫 SQL。當您已經熟悉這些資料表時,這沒有問題。但如果您今天早上才拿到檔案,而會議就在今天下午,這種方法就顯得太慢了。
更快捷的途徑是直接提出問題。Powerdrill Bloom 讓您能夠使用自然語言處理資料,並返回附帶來源的答案。其首頁承諾「每個數字都會附帶相應的分頁、資料列以及背後的數據」。在此基礎上,同一個工作區還可以生成圖表、試算表或簡報。
如果這是您的日常工作流程,有兩個相關頁面值得了解。Chat with Database 介紹了進入結構化資料的對話式途徑,而 Text to SQL 則適用於您需要查詢語句本身的情況。如果您的交付資料是平面匯出檔,CSV AI assistant 頁面則介紹了該解決路徑。
標頭告訴您的另一件事
由於分頁大小位於固定的偏移量處,因此在正式開啟檔案之前,您可以了解一些有用的資訊。使用 4,096 位元組分頁建立的資料庫,其行為與使用 65,536 位元組分頁建立的資料庫不同。這個選擇是在建立檔案時就做好的。
這不是您事後可以隨意更改的數字。它屬於與綱要決策相同的範疇,而不是一個簡單的設定。
結論
SQLite 檔案是封裝在單一產物中的完整資料庫。它包含一個 16 位元組的特徵標記、記錄在偏移量 16 處的分頁大小,以及一疊承載著您的資料表和索引的固定大小分頁。它便於傳輸、保留了資料型態,且能多年保持可讀性。
請記住規格說明書中特別提醒的一個注意事項:完整狀態通常在該檔案中。但在交易過程中,部分狀態會存在於旁邊的回復日誌或預寫式日誌中。在信任該複本之前,請先檢查是否有這些附屬檔案。
當您拿到檔案且需要的是答案而非綱要時,請嘗試 Powerdrill Bloom,並直接針對資料提出您的問題。
常見問題
.db、.sqlite 和 .sqlite3 有什麼不同?
結構上沒有任何不同。這三者都是同一格式的常用副檔名,而真正的識別標誌是檔案開頭 16 位元組的標頭字串 SQLite format 3\000。
我該如何知道 SQLite 檔案使用的分頁大小?
它記錄在標頭中。偏移量 16 處的 2 位元組整數保存著以位元組為單位的分頁大小。它必須是 512 到 32768 之間的 2 的冪次方,或者是代表 65536 的值 1。
SQLite 檔案是完整的資料庫嗎?
通常是,但並不總是如此。官方文件指出,在交易過程中,SQLite 會將額外資訊保留在回復日誌中。在 WAL 模式下,這些資訊則會寫入預寫式日誌中。
我可以在 Excel 中開啟 SQLite 檔案嗎?
無法直接開啟,因為該檔案儲存的是 B-tree 分頁,而不是文字資料列。常見的方法是先將資料表匯出為 CSV,或者使用能夠讀取該資料庫格式並返回結果的工具。
SQLite 可以免費商用嗎?
是的。SQLite 指出其程式碼屬於公有領域,並且「可免費用於任何目的,無論是商業還是私人用途。」