indexeddb 需按数据库思维设计:分对象仓库建表、建复合索引、批量事务写入、游标流式查询,并通过版本升级、错误监听和定期清理保障稳定性。

IndexedDB 存储大量结构化数据,关键不在“能不能存”,而在“怎么组织、怎么写、怎么查”。它不是 localStorage 的放大版,而是需要按数据库思维来设计:建表(对象仓库)、加索引、分批事务、走游标。
结构设计:按业务建对象仓库,别堆成一张大表
比如存商品规格矩阵,不要把所有 SKU 组合塞进一条记录。应拆成三个对象仓库:
-
products:存商品基础信息,主键用
id -
specSchemas:存规格维度和可选值(如 { "颜色": ["红","蓝"], "尺码": ["S","M"] }),主键也用
productId -
skus:每条对应一个具体组合,主键可用复合键(如
[productId, specKey]),字段含price、stock、specValues
这样既避免单条记录过大(IndexedDB 单条建议控制在几 MB 内),又支持按商品查模板、按组合查库存等多路径访问。
写入优化:批量事务 + 分片,别单条循环
插入上千条 SKU 数据时,逐条 put() 会开上千次事务,性能断崖式下跌。正确做法是:
- 用一个
readwrite事务,同时操作多个仓库:db.transaction(['products','specSchemas','skus'], 'readwrite') - 每批控制在 100–500 条,用
store.put(item)连续调用,不 await 每次结果 - 大数据导入时,用
requestIdleCallback或 Web Worker 分片,留出主线程响应 UI
查询提速:索引 + IDBKeyRange,拒绝全表遍历
查“某商品下所有红色 SKU”,不能靠 openCursor() 遍历全表。要提前建索引:
- 在
skus仓库中创建复合索引:store.createIndex('byProductAndColor', ['productId', 'specValues.color']) - 查询时用范围匹配:
index.getAll(IDBKeyRange.bound([123, '红色'], [123, '红色'])) - 查时间范围数据(如最近 30 天日志):用
IDBKeyRange.bound('2026-07-14', '2026-08-13'),配合 timestamp 索引
海量结果不用 getAll() 一次性加载,改用 openCursor() 流式处理,内存更友好。
稳定性保障:版本升级、错误监听、定期清理
生产环境不能只管写进去,还得管住生命周期:
- 结构变更必须升级 version,并在
onupgradeneeded中安全迁移:检查旧 store 是否存在、复制数据、删旧字段 - 监听
onblocked,提示用户关闭旧标签页,避免新版本卡死 - 事务失败时检查
event.target.error.name,对QuotaExceededError做降级(如删旧缓存)或提示 - 定期清冗余数据:比如每月清一次 30 天未访问的缓存记录,或按访问频次删掉最冷的 10%
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











