SQLite 支援 BLOB 型別儲存二進位資料(圖片、文件等)。本文整理 C API 實作寫入與讀取流程,並探討大型二進位物件處理的限制與對策。
sqlite3 *db;
sqlite3_stmt *stmt;
char *buffer = ...; // 要寫入的二進位內容
int len = ...; // 實際長度
sqlite3_prepare_v2(db, "INSERT INTO tb(id, content) VALUES (?, ?)", -1, &stmt, NULL);
sqlite3_bind_int(stmt, 1, 10);
sqlite3_bind_blob(stmt, 2, buffer, len, SQLITE_TRANSIENT); // 複製資料
sqlite3_step(stmt);
sqlite3_finalize(stmt);
關鍵點:使用參數綁定避免 SQL 注入,SQLITE_TRANSIENT 讓 SQLite 自行複製記憶體,呼叫端可立即釋放 buffer。
適合大型 BLOB,避免一次性載入記憶體:
sqlite3_blob *blob;
sqlite3_blob_open(db, "main", "tb", "content", rowid, 0, &blob); // 唯讀
int len = sqlite3_blob_bytes(blob);
char *buf = malloc(len);
sqlite3_blob_read(blob, buf, len, 0); // 可指定 offset 讀取片段
sqlite3_blob_close(blob);
優勢:支援隨機存取、分塊讀寫,適合 GB 級大物件。
| 限制 | 說明 | 對策 |
|---|---|---|
| sqlite3_blob_write 無法改變長度 | 只能覆寫現有空間,無法擴充 | 預先插入最大可能長度的資料,或採用「刪除重寫」 |
| 單一 BLOB 大小受限於 SQLITE_MAX_LENGTH(預設 1GB) | 編譯時可調整,但記憶體壓力大 | 大檔案建議切片儲存、或改用檔案系統+資料庫存路徑 |
| sqlite3_blob_open 需知道 rowid | 無法直接用主鍵值開啟 | 先查詢主鍵對應的 rowid,或在表建立時使用 INTEGER PRIMARY KEY 使主鍵即 rowid |
SQLite 處理二進位資料機制完善,但大檔案場景需權衡資料庫與檔案系統優劣,選擇最適架構。