瀏覽器中由來源私人檔案系統支援的 SQLite Wasm

使用 SQLite 在線上高效處理您所有的儲存空間需求。

關於 SQLite

SQLite 是熱門的開放原始碼,輕量級的嵌入式關聯資料庫管理系統。許多開發人員都會以結構化且易於使用的方式儲存資料,SQLite 的規模較小和記憶體需求很低,因此在行動裝置、桌面應用程式和網路瀏覽器中,經常會做為資料庫引擎使用。

SQLite 的一項主要功能是採用無伺服器資料庫,也就是說,不需要獨立的伺服器程序即可運作。而是儲存在使用者裝置上的單一檔案,方便整合至應用程式。

SQLite 標誌。

以 Web 組件為基礎的 SQLite

有許多以 Web Assembly (Wasm) 為基礎的非官方 SQLite 版本,允許在網路瀏覽器中使用,例如 sql.jssqlite3 WASM/JS 子專案是第一項努力,它與 SQLite 專案正式相關聯,讓程式庫是受支援 SQLite 可交付項目系列的程式庫建立而成的 Wasm 版本。這項專案的具體目標包括:

  • 繫結最靠近 C 的低階 sqlite3 API,在用法上可行。
  • 更高階的物件導向 API,較像 sql.jsNode.js 樣式實作,更直接採用低階 API。這個 API 必須透過與低階 API 相同的執行緒使用。
  • 以 worker 為基礎的 API,可透過 worker 訊息與先前的 API 通訊。這適合在主執行緒中使用,並安裝在背景工作執行緒中的較低層級 API,並透過工作站訊息與這些 API 通訊。
  • 以 Promise 為基礎的 Worker API 變化版本,可完全隱藏使用者之間的跨執行緒通訊層面。
  • 支援使用可用的 JavaScript API 的永久用戶端儲存空間,包括來源私人檔案系統 (OPFS)。

搭配來源私人檔案系統持續性後端使用 SQLite Wasm

從 npm 安裝程式庫

使用下列指令從 npm 安裝 @sqlite.org/sqlite-wasm 套件:

npm install @sqlite.org/sqlite-wasm

原始私人檔案系統

來源私人檔案系統 (OPFS,是 File System Access API 的一部分) 增強了,具有特殊的介面,可以帶來高效能的資料存取。與現有途徑不同的是,這個新途徑提供檔案內容的就地寫入權限,並具備專屬寫入權限。這項變更,除了能夠一致地讀取未清除的修改內容,以及專屬工作站上同步變數的可用性,能大幅提高效能並解除封鎖新的用途。

如您所想,專案目標的最後一點是支援使用可用 JavaScript API 的永久用戶端儲存空間,同時也必須注意將資料保存至資料庫檔案時,必須遵守嚴格的效能要求。這時來源私人檔案系統就會派上用場,更明確地說,FileSystemFileHandle 物件的 createSyncAccessHandle() 方法會派上用場。這個方法會傳回 Promise,這個 Promise 會解析為 FileSystemSyncAccessHandle 物件,可用於同步讀取與寫入檔案。此方法的同步性質可帶來效能優勢,但只能在專屬網路工作站內,針對來源私人檔案系統中的檔案使用,因此無法封鎖主執行緒。

設定必要標頭

除了其他檔案之外,下載的 SQLite Wasm 封存檔還包含 sqlite3.jssqlite3.wasm 檔案,這些檔案則構成 sqlite3 WASM/JS 版本。jswasm 目錄包含核心 sqlite3 交付項目,頂層目錄包含示範和測試應用程式。瀏覽器不會透過 file:// 網址提供 Wasm 檔案,因此您使用此方法建構的所有應用程式時,都需要使用網路伺服器,而且該伺服器在提供檔案時必須在回應中加入下列標頭:

這些標頭的原因是 SQLite Wasm 依附於 SharedArrayBuffer,設定這些標頭是安全性需求的一部分。

使用開發人員工具檢查流量時,應會看到以下資訊:

上述兩個標頭在 Chrome 開發人員工具中醒目顯示,分別是 Cross-Origin-Embedder-Policy 和 Cross-Origin-Opener-Policy。

速度測試

與已淘汰的 Web SQL 相比,SQLite 團隊已在他們的 WebAssembly 實作上執行一些基準測試。根據這些基準,SQLite Wasm 大致上與 Web SQL 的一樣快。有時速度稍微變慢 有時速度比較快詳情請參閱結果頁面

入門程式碼範例

如前所述,具有來源私人檔案系統持續性後端的 SQLite Wasm 需要從工作站環境執行。好消息是程式庫會自動處理所有這些作業,您可以直接從主執行緒使用。

import { sqlite3Worker1Promiser } from '@sqlite.org/sqlite-wasm';

(async () => {
  try {
    console.log('Loading and initializing SQLite3 module...');

    const promiser = await new Promise((resolve) => {
      const _promiser = sqlite3Worker1Promiser({
        onready: () => {
          resolve(_promiser);
        },
      });
    });

    console.log('Done initializing. Running demo...');

    let response;

    response = await promiser('config-get', {});
    console.log('Running SQLite3 version', response.result.version.libVersion);

    response = await promiser('open', {
      filename: 'file:worker-promiser.sqlite3?vfs=opfs',
    });
    const { dbId } = response;
    console.log(
      'OPFS is available, created persisted database at',
      response.result.filename.replace(/^file:(.*?)\?vfs=opfs$/, '$1'),
    );

    await promiser('exec', { dbId, sql: 'CREATE TABLE IF NOT EXISTS t(a,b)' });
    console.log('Creating a table...');

    console.log('Insert some data using exec()...');
    for (let i = 20; i <= 25; ++i) {
      await promiser('exec', {
        dbId,
        sql: 'INSERT INTO t(a,b) VALUES (?,?)',
        bind: [i, i * 2],
      });
    }

    console.log('Query data with exec()');
    await promiser('exec', {
      dbId,
      sql: 'SELECT a FROM t ORDER BY a LIMIT 3',
      callback: (result) => {
        if (!result.row) {
          return;
        }
        console.log(result.row);
      },
    });

    await promiser('close', { dbId });
  } catch (err) {
    if (!(err instanceof Error)) {
      err = new Error(err.result.message);
    }
    console.error(err.name, err.message);
  }
})();

操作示範

請參閱示範中上述程式碼的實際運作情形。請務必查看 Glitch 上的原始碼。請注意,下列嵌入版本不會使用 OPFS 後端,但當您在另一個分頁開啟示範模式時,將會使用此功能。

對來源私人檔案系統進行偵錯

如要對 SQLite Wasm 的來源私人檔案系統輸出進行偵錯,請使用 OPFS Explorer Chrome 擴充功能。

Chrome 線上應用程式商店中的 OPFS Explorer。

安裝擴充功能後,請開啟 Chrome 開發人員工具並選取「OPFS Explorer」分頁標籤,接著就能檢查 SQLite Wasm 寫入來源私人檔案系統的內容。

OPFS Explorer Chrome 擴充功能顯示試用版應用程式的來源私人檔案系統結構。

在開發人員工具的 OPFS Explorer 視窗中點選任何檔案,就能將檔案儲存至本機磁碟。接著,您可以使用 SQLite 檢視器等應用程式檢查資料庫,確定 SQLite Wasm 能正常運作。

這個 SQLite Viewer 應用程式可用來開啟 SQLite Wasm 試用版中的資料庫檔案。

取得協助與提供意見

SQLite Wasm 是由 SQLite 社群開發及維護。如要取得協助並提供意見,請搜尋支援論壇並張貼問題。如需完整的說明文件,請參閱 SQLite 網站。

特別銘謝

Tobias FischerUnsplash 上提供的主頁橫幅。