IndexedDB 中使用 get() 方法按主键精确读取单条记录最快,时间复杂度接近 O(1),需正确定义 keyPath 或 autoIncrement 主键,确保事务有效并正确处理未命中情况。

IndexedDB 中使用主键快速读取单条记录,关键在于利用 object store 的 key path 或 autoIncrement 主键,并通过 get() 方法直接按主键查询,时间复杂度接近 O(1)。
确保主键已正确定义
创建 object store 时必须明确指定主键方式:
- 若数据自带唯一字段(如
id),用keyPath声明:db.createObjectStore('users', { keyPath: 'id' }); - 若无自然主键,启用自增主键:
db.createObjectStore('logs', { autoIncrement: true });,此时主键由 IndexedDB 自动分配(数字类型) - 避免使用
{ keyPath: null, autoIncrement: false }—— 这会导致每条记录需手动传入 key,且无法用get()直接查
用 get() 方法按主键精确读取
get(key) 是最直接、最快的方式,只查一条,不触发游标遍历:
- 主键为字符串或数字均可,类型需与存储时一致:
const request = store.get(123); // 查 id=123 的用户 - 支持复合主键(较少用),但 key 必须是完整数组:
db.createObjectStore('orders', { keyPath: ['userId', 'orderId'] });
查询时:store.get([1001, 'ORD-789']); - 返回 Promise 包裹的 IDBRequest,监听
onsuccess获取结果:request.onsuccess = () => { console.log(request.result); };
注意事务生命周期和错误处理
get() 必须在有效事务中执行,且事务不能提前结束:
立即学习“Java免费学习笔记(深入)”;
- 事务默认在所有请求完成(包括异步回调)后自动关闭,但若回调里有延迟操作(如 setTimeout),需手动延长:
transaction.oncomplete = () => { /* 确保此时事务仍有效 */ }; - 主键不存在时
result为undefined,不是错误,无需 try/catch:if (request.result === undefined) console.log('未找到记录'); - 仅当数据库被删除、对象库名错误、或事务已 abort 时才会触发
onerror
对比其他读取方式:为什么 get() 最快
相比其他方法,get() 绕过了索引查找和游标迭代:
-
getAll()或openCursor()会扫描全部或范围数据,即使只想要一条 -
index.get()虽也能查,但走的是二级索引路径,比主键get()多一层映射,性能略低 - 主键查询由底层 B+ 树直接定位,无需额外索引维护开销


















