SQLite を使用して、ウェブ上のすべてのストレージ ニーズをパフォーマンスよく処理します。
SQLite は、よく利用されているオープンソースの軽量な組み込みリレーショナル データベース管理システムです。多くのデベロッパーが、構造化された使いやすい方法でデータを保存するために使用しています。SQLite はサイズが小さく、メモリ要件が低いため、モバイル デバイス、デスクトップ アプリケーション、ウェブブラウザのデータベース エンジンとしてよく利用されます。
SQLite の主な特長の 1 つは、サーバーレス データベースであることです。つまり、動作に個別のサーバー プロセスを必要としません。代わりに、データベースはユーザーのデバイス上の単一のファイルに保存されるため、アプリケーションに簡単に統合できます。
Web アセンブリに基づく SQLite
Web Assembly(Wasm)に基づく非公式の SQLite バージョンが多数存在し、ウェブブラウザで使用できます(例: sql.js)。sqlite3 WASM/JS サブプロジェクトは、SQLite プロジェクトに正式に関連付けられた最初の取り組みであり、ライブラリの Wasm ビルドをサポートされている SQLite 成果物のファミリーの確立されたメンバーにしています。このプロジェクトの具体的な目標は次のとおりです。
- 使用方法の点で C 言語の API にできるだけ近い低レベルの sqlite3 API をバインドします。
- sql.js や Node.js スタイルの実装に似た、低レベル API に直接アクセスする高レベルのオブジェクト指向 API。この API は、低レベル API と同じスレッドから使用する必要があります。
- Worker メッセージを介して以前の API と通信する Worker ベースの API。これはメインスレッドでの使用を想定しており、下位レベルの API はワーカー スレッドにインストールされ、ワーカー メッセージを介して通信します。
- ユーザーからスレッド間の通信の側面を完全に隠す、Worker API の Promise ベースのバリアント。
- Origin Private File System(OPFS)など、利用可能な JavaScript API を使用した永続的なクライアントサイド ストレージのサポート。
Origin Private File System 永続バックエンドでの SQLite Wasm の使用
npm からライブラリをインストールする
次のコマンドを使用して、npm から @sqlite.org/sqlite-wasm パッケージをインストールします。
npm install @sqlite.org/sqlite-wasm
オリジン プライベート ファイル システム
オリジン プライベート ファイル システム(OPFS、ファイル システム アクセス API の一部)は、データへの非常にパフォーマンスの高いアクセスを実現する特別なサーフェスで拡張されています。この新しいサーフェスは、ファイルのコンテンツへのインプレースの排他的書き込みアクセスを提供することで、既存のサーフェスとは異なります。この変更により、フラッシュされていない変更を常に読み取れるようになり、専用ワーカーで同期バリアントを使用できるようになるため、パフォーマンスが大幅に向上し、新しいユースケースが実現します。
プロジェクトの目標の最後のポイントである「利用可能な JavaScript API を使用した永続的なクライアントサイド ストレージのサポート」には、データベース ファイルへのデータの永続化に関する厳しいパフォーマンス要件が伴います。ここで、オリジン プライベート ファイル システム、より具体的には FileSystemFileHandle
オブジェクトの createSyncAccessHandle()
メソッドが役に立ちます。このメソッドは、ファイルを同期的に読み書きするために使用できる FileSystemSyncAccessHandle
オブジェクトに解決される Promise を返します。このメソッドは同期処理であるため、パフォーマンス上のメリットがありますが、メインスレッドがブロックされないように、オリジン プライベート ファイル システム内のファイル専用の Web Worker 内でのみ使用できます。
必要なヘッダーの設定
ダウンロードした SQLite Wasm アーカイブには、sqlite3 WASM/JS ビルドを構成する sqlite3.js
ファイルと sqlite3.wasm
ファイルが含まれています。jswasm
ディレクトリには、コア sqlite3 の成果物が含まれ、最上位ディレクトリにはデモアプリとテストアプリが含まれます。ブラウザは file://
URL から Wasm ファイルを提供しないため、これを使用してビルドするアプリにはウェブサーバーが必要です。また、そのサーバーは、ファイルを提供するときにレスポンスに次のヘッダーを含める必要があります。
Cross-Origin-Opener-Policy
は、ブラウジング コンテキストを同一オリジンのドキュメントのみに分離するsame-origin
ディレクティブに設定されます。クロスオリジン ドキュメントは同じブラウジング コンテキストに読み込まれません。Cross-Origin-Embedder-Policy
がrequire-corp
ディレクティブに設定されているため、ドキュメントは同じオリジンからのリソース、または別のオリジンから読み込み可能として明示的にマークされたリソースのみを読み込むことができます。
これらのヘッダーが必要なのは、SQLite Wasm が SharedArrayBuffer
に依存しており、これらのヘッダーの設定が セキュリティ要件の一部であるためです。
DevTools でトラフィックを調べると、次の情報が表示されます。
Speedtest
SQLite チームは、非推奨の Web SQL と比較して、WebAssembly 実装でベンチマークを実行しました。これらのベンチマークは、SQLite Wasm が一般的に Web SQL と同程度の速度であることを示しています。少し遅くなることもあれば、少し速くなることもあります。詳細は、結果ページをご覧ください。
スタートガイドのコードサンプル
前述のように、Origin Private File System 永続性バックエンドを使用する SQLite Wasm は、Worker コンテキストから実行する必要があります。このライブラリは、これらの処理をすべて自動的に行ってくれるため、メインスレッドから直接使用できます。
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);
}
})();
デモ
上記のコードの動作については、デモをご覧ください。GitHub のソースコードもご確認ください。以下の埋め込みバージョンでは OPFS バックエンドが使用されていませんが、別のタブでデモを開くと使用されることに注意してください。
Origin Private File System をデバッグする
SQLite Wasm の Origin Private File System の出力をデバッグするには、OPFS Explorer Chrome 拡張機能を使用します。
拡張機能をインストールしたら、Chrome DevTools を開き、[OPFS Explorer] タブを選択します。これで、SQLite Wasm がオリジン プライベート ファイル システムに書き込む内容を検査する準備が整いました。
DevTools の OPFS エクスプローラ ウィンドウでファイルを選択すると、ローカル ディスクに保存できます。その後、SQLite Viewer などのアプリを使用してデータベースを検査し、SQLite Wasm が実際に約束どおりに動作していることを確認できます。
ヘルプを利用する、フィードバックを送信する
SQLite Wasm は、SQLite コミュニティによって開発および保守されています。サポート フォーラムで検索したり投稿したりして、ヘルプを利用したりフィードバックを送信したりできます。完全なドキュメントは、SQLite サイトで入手できます。