IndexedDB (idb)介紹
一、IndexedDB 是什麼?
IndexedDB 是瀏覽器內建的一個 NoSQL 資料庫,專門用來在使用者端(client-side)儲存大量結構化資料。
和 localStorage
或 sessionStorage
不一樣,IndexedDB 有這些特點:
-
容量大:可儲存 MB ~ GB 等級的資料(依瀏覽器不同而異),不像 localStorage 只有大約 5MB 限制。
-
結構化儲存:支援物件 (Object) 儲存,資料格式不限於字串。
-
具索引能力:能建立 index,讓你快速查詢資料。
-
非同步 API:操作 IndexedDB 幾乎都是非同步,避免阻塞 UI。
-
交易機制 (transaction):保證操作的原子性,類似資料庫的事務。
二、idb 是什麼?
雖然 IndexedDB 功能很強大,但 原生 API 很繁瑣,需要處理大量 callback 和事件監聽。
因此社群有人開發了 idb 套件(npm: idb),用 Promise / async-await 方式封裝,讓 IndexedDB 用起來更直覺,程式碼簡潔。
三、IndexedDB 的結構
IndexedDB 的結構有點像傳統資料庫:
-
Database (資料庫) → 一個網站可以有多個 DB。
-
Object Store (物件儲存空間) → 類似資料表 (table)。
-
Record (紀錄) → 存放在 Object Store 裡的資料,通常是一個物件。
-
Key (鍵) → 每筆資料必須有唯一的 key,用來檢索。
-
Index (索引) → 類似 SQL 的索引,方便快速查詢。
四、使用 idb 的範例
1. 安裝
npm install idb
2. 建立資料庫
import { openDB } from 'idb';
// 建立資料庫,並設定版本與物件存放區
const dbPromise = openDB('my-database', 1, {
upgrade(db) {
// 建立一個 object store (類似 table),以 id 當主鍵
db.createObjectStore('users', { keyPath: 'id' });
},
});
3. 新增資料
async function addUser(user) {
const db = await dbPromise;
await db.add('users', user);
}
// 範例資料
addUser({ id: 1, name: 'Aria', email: 'aria@example.com' });
4. 讀取資料
async function getUser(id) {
const db = await dbPromise;
return db.get('users', id);
}
getUser(1).then(user => console.log(user));
5. 更新資料
async function updateUser(user) {
const db = await dbPromise;
await db.put('users', user); // put 會新增或覆蓋
}
updateUser({ id: 1, name: 'Aria Updated', email: 'aria@example.com' });
6. 刪除資料
async function deleteUser(id) {
const db = await dbPromise;
await db.delete('users', id);
}
deleteUser(1);
7. 取得所有資料
async function getAllUsers() {
const db = await dbPromise;
return db.getAll('users');
}
getAllUsers().then(users => console.log(users));
五、什麼時候適合用 IndexedDB (idb)?
-
需要離線存取:像是 PWA(漸進式網頁應用)要讓使用者離線也能用。
-
大量資料:例如地圖快取、圖片、JSON 資料。
-
比 localStorage 更進階的結構化查詢需求。
-
需要快取 API 回應,減少重複請求。
六、總結
-
IndexedDB = 瀏覽器端的 NoSQL 資料庫,適合大量資料與離線應用。
-
idb = 幫助你用 Promise/async 方式操作 IndexedDB 的工具,語法簡單、直覺。
-
適合應用場景:PWA、快取 API、需要在本地端存很多資料的專案。