IndexedDB
セッション情報は保存してはならない
stringに限らないデータをブラウザに保存できる
型情報(e.g. integer, float)も保存できる
主キーの設定
インデックス生成などの操作
トランザクションの作成
データの一貫性も担保
tutorial
gpt-5.icon
IndexedDB は、ブラウザに組み込まれた非同期のローカルデータベースで、大量データの保存・検索を高速に行える仕組みです。Web アプリがオフラインでも動作できるようにするための中核技術の1つでもあります。
🗄️ IndexedDB の特徴
✔ NoSQL(オブジェクトストア型)
RDB のようなテーブルではなく、オブジェクトをそのまま保存できます。
code:ts
{
id: 1,
name: "Alice",
}
✔ 非同期 API(Promise / event ベース)
IO 操作なので非同期。最近は indexedDB.open() を Promise 化するライブラリを使うのが一般的。
✔ 大容量保存が可能
localStorage の 5MB に比べて、数百MB〜数GB まで保存できる場合もあります。
✔ トランザクション対応
複数操作をまとめて実行し、一貫性を確保できる。
✔ ブラウザに永続化
タブを閉じてもデータは残り、アプリのキャッシュやオフラインデータ保持に向いています。
🧩 IndexedDB の構造
code:_
Database
├─ Object Store(RDBでいうテーブル)
│ └─ Records(オブジェクト)
└─ Index(検索の高速化)
Object Store
主キー(keyPath)を持つ
値は JSON と互換性のある任意の JS オブジェクト
Index
name などのフィールドで検索を高速化
複合 index も可能
📦 基本的な使い方(生 API 版)
データベースを開く
code:ts
const request = indexedDB.open("my-db", 1);
request.onupgradeneeded = (event) => {
const db = request.result;
db.createObjectStore("users", { keyPath: "id" });
};
データを保存
code:ts
const db = request.result;
const tx = db.transaction("users", "readwrite");
const store = tx.objectStore("users");
store.put({ id: 1, name: "Alice" });
データを取得
code:ts
store.get(1).onsuccess = (ev) => {
console.log(ev.target.result);
};
🧰 実務では Promise 化されたラッパーを使うのが定番
生 IndexedDB は イベントベース API が非常に扱いにくい ため、
実務では以下のどれかを使うのが一般的です。
一番有名・軽量で、Promise ベース。
code:_
npm i idb
code:ts
import { openDB } from "idb";
const db = await openDB("my-db", 1, {
upgrade(db) {
db.createObjectStore("users", { keyPath: "id" });
},
});
await db.put("users", { id: 1, name: "Alice" });
const user = await db.get("users", 1);
高機能で ORM っぽく書ける。
🧭 何に使えるか?
1. オフラインキャッシュ
API レスポンスを保存して、接続が切れてても動作可能に
2. 検索結果のローカルキャッシュ
ユーザーの求人検索履歴や条件を IndexedDB に保持 →
次回高速に検索結果を返す、などの用途と相性抜群。
3. PWA のデータ保存
offline-first アプリの DB として定番
4. 大きなデータの保存
画像バイナリ、ログ、大量のオブジェクトなど
5. フロントの state 永続化
React Query・Apollo のキャッシュの永続化にも利用されます。