什么是 IndexedDB?
IndexedDB(Indexed Database API)是一种浏览器提供的 NoSQL 数据库,支持在客户端存储大量结构化数据。它比 localStorage 容量更大,支持事务、索引并且性能优越,特别适合用于构建需要离线功能或数据缓存的应用。IndexedDB 已成为 W3C 标准,并获得主流浏览器广泛支持。
IndexedDB 的基本结构与特性
IndexedDB 允许创建多个数据库,每个数据库包含多个“对象存储”(object stores 类似于表),并可以为数据创建索引。所有操作都基于事务执行,保证数据一致性。此外,IndexedDB 提供 版本管理机制,可在升级数据库结构时执行 schema 更改。
使用教程:一步步掌握 IndexedDB
1. 检查浏览器支持与打开数据库
if (!('indexedDB' in window)) {
console.error('当前浏览器不支持 IndexedDB');
}
const request = indexedDB.open('MyDatabase', 1);
这会创建(或打开)一个名为 MyDatabase、版本为 1 的数据库实例。
2. 创建对象存储与索引(升级场景)
request.onupgradeneeded = event => {
const db = event.target.result;
const store = db.createObjectStore('Todos', { keyPath: 'id', autoIncrement: true });
store.createIndex('by_title', 'title', { unique: false });
};
如果版本升级或为首次创建,该事件触发,用于定义数据库结构。
3. 成功连接数据库
request.onsuccess = event => {
const db = event.target.result;
// 后续操作使用 db 对象
};
request.onerror = event => {
console.error('打开数据库失败:', event.target.errorCode);
};
4. 执行增删改查操作(CRUD)
const tx = db.transaction('Todos', 'readwrite');
const store = tx.objectStore('Todos');
store.add({ title: '写文章', done: false });
tx.oncomplete = () => console.log('新增成功');
读取某条记录:
const tx = db.transaction('Todos', 'readonly');
const store = tx.objectStore('Todos');
const getRequest = store.get(1);
getRequest.onsuccess = () => console.log('查询结果:', getRequest.result);
5. 使用 modern wrapper(Promise 方式)
推荐使用 idb 等 Promise 封装库,提高代码可读性。
import { openDB } from 'idb';
const db = await openDB('MyDB', 1, {
upgrade(db) {
const store = db.createObjectStore('Tasks', { keyPath: 'id', autoIncrement: true });
store.createIndex('name', 'name');
}
});
await db.add('Tasks', { name: '学习 IndexedDB' });
const task = await db.get('Tasks', 1);
console.log(task);
这种写法更简洁,易于维护。
IndexedDB 的典型使用场景
- 离线 Web 应用:如 PWA 存储用户数据缓存在客户端。
- 大数据处理:存储图片、日志、聊天历史等大量数据。
- 复杂查询需求:可通过索引高效检索。
- 本地缓存机制:缓存 API 返回内容,减少网络请求量。
Reddit 社区用户分享:在教育应用中 用 IndexedDB 存储 TB 级图片缓存、聊天记录、离线填报等场景更适合它而非 localStorage(容量仅 5MB)。
实用技巧与注意事项
- 结构升级谨慎处理:合理使用 onupgradeneeded,避免数据迁移问题。
- 事务保证一致性:所有写读操作应包裹在事务里防止中途异常破坏数据。
- 错误处理不可少:注册 onerror 回调,捕获异常用于容错或恢复策略。
- 适当使用索引与游标:提高查询效率,也便于分页或范围检索操作。
- 保持 clear DB:应用版本迭代时合理清理不再使用的对象存储,避免历史冗余。
- 兼容性考虑:虽主流浏览器支持完整 IndexedDB,但仍建议做 feature detect 并提供 fallback 方案(如 localStorage 或消息提示用户更新)。
IndexedDB 是一个功能强大、适用范围广的浏览器客户端数据库,特别适合存储大量结构化数据与离线场景。