核心特性
- NoSQL存储:自由存储结构化数据(支持JSON对象)
- 事务支持:ACID事务保证数据一致性
- 索引系统:支持多字段索引查询(最大支持256个索引)
- 异步API:所有操作不阻塞主线程
- 大容量:Chrome默认允许存储网站数据的60%(最高可达80%硬盘空间)
- 离线支持:PWA应用的核心存储方案
快速入门
生命周期管理
- 开启数据库 :
indexedDB.open(name, version)
- 版本升级 :在
onupgradeneeded
中修改结构
- 对象仓库:类似SQL的表结构
- 事务操作:所有数据操作必须通过事务
核心对象关系
css
复制代码
Database → ObjectStore → Index
↑
Transaction → Cursor
完整代码示例
1. 数据库初始化
javascript
复制代码
const DB_NAME = 'userDB';
const STORE_NAME = 'userProfile';
const DB_VERSION = 3; // 每次结构变更递增版本
const dbRequest = indexedDB.open(DB_NAME, DB_VERSION);
dbRequest.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains(STORE_NAME)) {
// 创建对象仓库
const store = db.createObjectStore(STORE_NAME, {
keyPath: 'userId',
autoIncrement: false
});
// 创建复合索引
store.createIndex('age_gender', ['age', 'gender'], { unique: false });
// 唯一约束索引
store.createIndex('email', 'email', { unique: true });
}
// 版本2新增登录时间索引
if (event.oldVersion < 2) {
const store = event.target.transaction.objectStore(STORE_NAME);
store.createIndex('lastLogin', 'loginTimestamp', { unique: false });
}
};
dbRequest.onsuccess = (event) => {
const db = event.target.result;
db.onversionchange = () => db.close(); // 安全关闭监听
};
2. 数据操作
事务封装方法
javascript
复制代码
async function executeTransaction(db, storeNames, mode, operation) {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeNames, mode);
transaction.oncomplete = () => resolve();
transaction.onerror = (e) => reject(e.target.error);
operation(transaction);
});
}
增删改查实现
javascript
复制代码
// 批量写入
async function bulkWrite(db, items) {
await executeTransaction(db, [STORE_NAME], 'readwrite', (tx) => {
const store = tx.objectStore(STORE_NAME);
items.forEach(item => store.put(item));
});
}
// 条件更新
async function conditionalUpdate(db, userId, updates) {
const user = await getRecord(db, userId);
if (user.loginCount > 5) {
await updateRecord(db, { ...user, ...updates });
}
}
// 分页查询
async function paginatedQuery(db, indexName, range, pageSize, pageNumber) {
return new Promise((resolve) => {
const transaction = db.transaction([STORE_NAME]);
const store = transaction.objectStore(STORE_NAME);
const index = store.index(indexName);
const results = [];
let count = 0;
let advanced = false;
index.openCursor(range).onsuccess = (event) => {
const cursor = event.target.result;
if (!cursor) return resolve(results);
if (!advanced && pageNumber > 1) {
cursor.advance((pageNumber - 1) * pageSize);
advanced = true;
return;
}
results.push(cursor.value);
if (++count >= pageSize) return resolve(results);
cursor.continue();
};
});
}
架构原理
存储结构
层级 |
说明 |
限制 |
Database |
数据库容器 |
同源下可创建多个 |
ObjectStore |
数据存储实体 |
每个DB最多300个 |
Index |
索引加速查询 |
每个Store最多256个索引 |
Cursor |
数据遍历迭代器 |
自动管理内存 |
事务模型
- 作用域:预定义ObjectStore集合
- 模式:readonly(默认) / readwrite / versionchange
- 自动提交:约1秒无操作自动提交
- 错误处理:事务中任一操作失败则整体回滚
浏览器兼容指南
支持矩阵
浏览器 |
支持版本 |
存储配额策略 |
Chrome |
24+ |
按磁盘空间比例 |
Firefox |
16+ |
独立于SQLite存储 |
Safari |
8+ |
严格7天LRU清理策略 |
Edge |
12+ |
继承IE10+实现 |
容量估算
javascript
复制代码
navigator.storage.estimate().then(estimate => {
console.log(`可用空间:${estimate.quota / 1024 ** 2} MB`);
console.log(`已用空间:${estimate.usage / 1024 ** 2} MB`);
});
最佳实践场景
推荐场景
- 离线优先应用(如PWA)
- 客户端分析数据存储
- 富文本自动保存
- 媒体资源元数据管理
- 实时协作应用状态同步
性能对比
操作类型 |
localStorage |
IndexedDB |
10KB写入 |
0.2ms |
2ms |
10MB写入 |
阻塞 |
120ms |
条件查询 |
不可 |
8ms |
万级数据遍历 |
阻塞 |
45ms |
专家级技巧
高级优化
- 批量写入:合并操作减少事务开销
- 游标复用:使用advance()实现快速分页
- 内存管理:合理设置keyRange避免全表扫描
- 压缩策略:存储前使用JSON.stringify压缩
- Worker集成:将复杂操作移入Web Worker
调试技巧
javascript
复制代码
// 查看所有数据库
indexedDB.databases().then(dbs =>
console.log('现有数据库:', dbs)
);
// 性能监测
const start = performance.now();
transaction.oncomplete = () =>
console.log(`事务耗时:${performance.now() - start}ms`);
资源推荐
工具库
- idb:Promise封装库(2KB)
- Dexie.js:类ORM高级封装
- localForage:自动降级存储方案
调试工具
- Chrome DevTools IndexedDB面板
- Firedox Storage Inspector
- Safari Web Inspector
扩展阅读
通过本指南,您已掌握IndexedDB从基础到高级的完整知识体系。建议在实际项目中结合Service Worker和Cache API构建完整的离线解决方案。