indexeddb适合存储商品规格组合矩阵,应分层建模为products、specschemas、skus三张表,用复合主键和多字段索引支持高效查询,批量事务写入并结合游标读取优化性能。

IndexedDB 是浏览器端适合存储复杂结构化数据的方案,特别适合缓存商品规格组合矩阵这类多维、嵌套、需快速查询的数据。关键在于合理设计对象仓库(objectStore)结构、主键策略,以及用事务高效写入/查询。
设计合理的对象仓库结构
商品规格组合矩阵本质是“SKU 组合 → 属性值映射 + 库存/价格等状态”的关系。不建议把整个矩阵扁平化为单条记录,而应分层建模:
-
商品主表(products):存商品基础信息(id、name、defaultImage 等),主键为
productId -
规格模板表(specSchemas):存该商品支持的规格维度(如 ["颜色", "尺码", "版本"]),主键为
productId,字段如dimensions: ["颜色", "尺码"]、options: { "颜色": ["红色","蓝色"], "尺码": ["S","M","L"] } -
SKU 映射表(skus):每条记录对应一个具体组合,主键可设为复合键(如
productId + specKey,其中specKey是排序后属性值拼接字符串,如"红色_S"),字段含skuId、price、stock、specValues: { "颜色": "红色", "尺码": "S" }
这样设计便于按商品查规格模板,也支持按 specKey 快速定位 SKU;同时避免单条记录过大(IndexedDB 单条上限约 2GB,但实际建议控制在几 MB 内)。
用 compound key 或 keyPath 实现组合查询
要支持“查某商品下所有颜色为‘红色’的 SKU”,不能只靠主键。可在 skus 仓库中使用 index(索引):
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 创建多字段索引:
store.createIndex('byProductAndColor', ['productId', 'specValues.color'], { unique: false }) - 查询时用 IDBKeyRange:
index.getAll(IDBKeyRange.bound([123, '红色'], [123, '红色'], true, true)) - 若需更灵活匹配(如“颜色=红 OR 尺码=M”),可预计算并存一个
specTags字段(如["颜色_红色", "尺码_M"]),再建byTag多值索引(需配合multiEntry: true)
批量写入矩阵数据,避免逐条事务开销
一个商品可能有几十甚至上百个 SKU 组合,逐条 add() 会触发多次事务,性能差。应统一用一个事务批量写入:
- 打开事务时指定多个仓库:
const tx = db.transaction(['products', 'specSchemas', 'skus'], 'readwrite') - 获取各 store:
const prodStore = tx.objectStore('products'); const skuStore = tx.objectStore('skus'); - 先写
products和specSchemas,再用skus的put()批量插入数组(循环调用put()即可,同事务内自动合并) - 监听
tx.oncomplete确保全部成功,tx.onerror做回滚提示
读取时优先用索引 + 游标,避免全量 load
前端渲染规格选择器(如颜色按钮、尺码下拉)不需要加载全部 SKU 数据,只需维度选项和可用状态:
- 从
specSchemas读出options获取所有颜色/尺码列表 - 用游标遍历
skus中当前商品的记录:const req = skuStore.index('byProductId').openCursor(IDBKeyRange.only(productId)) - 在
req.onsuccess中收集specValues,构建“哪些颜色有货”、“哪些尺码在选中颜色下可用”等逻辑 - 对大矩阵,可加内存缓存(如 Map)避免重复游标遍历
不复杂但容易忽略的是版本升级——新增 specSchemas 表或修改 skus 主键时,必须在 onupgradeneeded 中重建仓库,并迁移旧数据。矩阵类数据一旦写入,尽量通过更新而非删库重来保证一致性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










