在Web应用开发中,当需要存储大量结构化数据且需要支持高效查询时,IndexedDB是比localStorage、sessionStorage更合适的选择,它提供了数据库级别的操作能力,支持存储大量数据并创建索引提升查询效率。

IndexedDB核心概念
在使用IndexedDB之前,需要先了解几个核心概念:
- 数据库:IndexedDB是按域名划分的,每个域名下可以有多个数据库,数据库有名称和版本号,版本升级时会触发更新逻辑。
- 对象存储空间:类似关系型数据库中的表,是存储数据的基本单元,创建数据库时需要同时创建对象存储空间,并且可以指定主键和索引。
- 索引:可以基于对象存储空间中数据的某个属性创建索引,后续可以通过索引快速查询数据,提升查询效率。
- 事务:所有对IndexedDB的读写操作都需要在事务中完成,事务可以保证一组操作的原子性,要么全部成功要么全部失败。
IndexedDB基本操作流程
1. 打开/创建数据库
使用indexedDB.open方法打开数据库,如果数据库不存在则会自动创建,该方法返回一个IDBOpenDBRequest对象,通过监听其事件来处理数据库打开的不同阶段。
// 打开名为userDB的数据库,版本号为1
const request = indexedDB.open('userDB', 1);
// 数据库升级时触发,首次创建数据库也会触发该事件
request.onupgradeneeded = function(event) {
const db = event.target.result;
// 创建名为userStore的对象存储空间,指定主键为id,自增
const objectStore = db.createObjectStore('userStore', { keyPath: 'id', autoIncrement: true });
// 基于userStore的name属性创建索引,允许重复值
objectStore.createIndex('name', 'name', { unique: false });
// 基于userStore的age属性创建索引,不允许重复值
objectStore.createIndex('age', 'age', { unique: true });
};
// 数据库打开成功
request.onsuccess = function(event) {
const db = event.target.result;
console.log('数据库打开成功', db);
};
// 数据库打开失败
request.onerror = function(event) {
console.error('数据库打开失败', event.target.error);
};
2. 添加数据
添加数据需要在读写事务中完成,首先开启事务,获取对象存储空间,然后调用add方法添加数据。
function addData(db, data) {
// 开启读写事务,操作userStore对象存储空间
const transaction = db.transaction(['userStore'], 'readwrite');
const store = transaction.objectStore('userStore');
// 添加数据
const addRequest = store.add(data);
addRequest.onsuccess = function() {
console.log('数据添加成功,主键为', addRequest.result);
};
addRequest.onerror = function(event) {
console.error('数据添加失败', event.target.error);
};
// 事务完成回调
transaction.oncomplete = function() {
console.log('事务完成');
};
}
// 调用添加数据方法
const dbRequest = indexedDB.open('userDB', 1);
dbRequest.onsuccess = function(event) {
const db = event.target.result;
addData(db, { name: '张三', age: 25, email: 'test@ipipp.com' });
};
3. 查询数据
查询数据分为按主键查询和按索引查询两种方式,按主键查询使用get方法,按索引查询需要先获取索引对象再调用get方法。
function getDataByKey(db, key) {
const transaction = db.transaction(['userStore'], 'readonly');
const store = transaction.objectStore('userStore');
const getRequest = store.get(key);
getRequest.onsuccess = function() {
if (getRequest.result) {
console.log('按主键查询到数据', getRequest.result);
} else {
console.log('未查询到对应主键的数据');
}
};
}
function getDataByIndex(db, indexName, indexValue) {
const transaction = db.transaction(['userStore'], 'readonly');
const store = transaction.objectStore('userStore');
const index = store.index(indexName);
const getRequest = index.get(indexValue);
getRequest.onsuccess = function() {
if (getRequest.result) {
console.log('按索引查询到数据', getRequest.result);
} else {
console.log('未查询到对应索引的数据');
}
};
}
// 调用查询方法
const dbRequest = indexedDB.open('userDB', 1);
dbRequest.onsuccess = function(event) {
const db = event.target.result;
// 按主键查询,假设主键为1
getDataByKey(db, 1);
// 按name索引查询
getDataByIndex(db, 'name', '张三');
};
4. 更新和删除数据
更新数据使用put方法,如果主键存在则更新,不存在则新增;删除数据使用delete方法,传入要删除的主键即可。
function updateData(db, data) {
const transaction = db.transaction(['userStore'], 'readwrite');
const store = transaction.objectStore('userStore');
const updateRequest = store.put(data);
updateRequest.onsuccess = function() {
console.log('数据更新成功');
};
}
function deleteData(db, key) {
const transaction = db.transaction(['userStore'], 'readwrite');
const store = transaction.objectStore('userStore');
const deleteRequest = store.delete(key);
deleteRequest.onsuccess = function() {
console.log('数据删除成功');
};
}
// 调用更新和删除方法
const dbRequest = indexedDB.open('userDB', 1);
dbRequest.onsuccess = function(event) {
const db = event.target.result;
// 更新主键为1的数据
updateData(db, { id: 1, name: '李四', age: 26, email: 'new@ipipp.com' });
// 删除主键为1的数据
deleteData(db, 1);
};
IndexedDB使用注意事项
- IndexedDB的存储空间通常有上限,不同浏览器的限制不同,一般在几十MB到几百MB不等,存储大量数据时需要注意容量限制。
- IndexedDB的操作都是异步的,所有操作都通过事件回调处理结果,不能使用同步的方式等待操作完成。
- 如果需要在不同页面之间共享IndexedDB数据,只要域名相同就可以访问,不需要额外处理跨页面通信。
- 浏览器隐私模式下可能会限制IndexedDB的使用,部分浏览器在隐私模式下不支持IndexedDB或者存储的数据会在关闭页面后清除。
- 操作完成后不需要手动关闭数据库,浏览器会自动管理数据库连接,频繁打开关闭数据库反而可能影响性能。
IndexedDB与其他客户端存储方案对比
为了更清晰地了解IndexedDB的适用场景,我们可以将其与其他常见的客户端存储方案做对比:
| 存储方案 | 存储容量 | 数据类型 | 查询能力 | 适用场景 |
|---|---|---|---|---|
| localStorage | 约5MB | 字符串 | 无,只能按key获取 | 存储少量简单键值对数据 |
| sessionStorage | 约5MB | 字符串 | 无,只能按key获取 | 存储当前会话的临时数据 |
| IndexedDB | 较大,一般几十到几百MB | 任意类型,包括对象、二进制数据等 | 支持索引查询,可高效查询大量数据 | 存储大量结构化数据,需要复杂查询的场景 |
使用IndexedDB进行客户端大数据存储时,合理设计对象存储空间和索引是提升性能的关键,避免创建过多不必要的索引,同时尽量批量操作数据减少事务开销。
IndexedDB客户端存储大数据存储Web_Storage修改时间:2026-06-27 16:30:37