IndexedDB中不存在“空记录”,但主键或索引字段为undefined/null/缺失会导致查询失败、游标跳过及索引失效等隐性问题;需在写入前校验、升级时修复、查询时兜底,并避免keyPath含非法字符。

IndexedDB 中不存在“空记录”概念,但确实存在 未定义主键、索引字段为 undefined/null、或索引字段缺失 导致的查询失败、游标跳过、甚至索引失效等问题。这些不是数据库报错,而是数据建模和写入逻辑疏漏引发的隐性陷阱。
主键为空或无效时的行为
当对象仓库(object store)设置了 keyPath,而插入对象中该路径值为 undefined、null、"" 或非合法 JavaScript 值(如 NaN、Symbol)时:
- 若未启用
autoIncrement: true,插入操作会直接抛出DataError,事务中止; - 若启用了
autoIncrement,系统将忽略 keyPath 值,自动生成数字主键,但该记录在按 keyPath 查询时永远无法命中; - 插入成功后,该记录仍存在于对象仓库中,但所有基于该 keyPath 的索引不会为其建立条目(即“索引遗漏”)。
索引字段缺失或为 null/undefined
创建索引时指定的字段(如 createIndex('byTag', 'tag')),若某条记录中 tag 字段不存在、为 null 或 undefined:
- 该记录不会被加入该索引,相当于“对这个索引不可见”;
-
index.get(value)或index.getAll(value)永远查不到它; - 使用游标遍历索引(
index.openCursor())时,它会被完全跳过; - 但通过对象仓库主键(
store.get(key))仍可读取该记录。
如何主动识别与规避这类问题
不能依赖运行时报错来发现空/无效索引数据,需在写入前校验、写入后验证、查询时兜底:
- 写入前做字段守卫:对关键索引字段(如
tag、createdAt)强制设默认值,避免undefined; - 升级数据库时批量修复:在
onupgradeneeded中遍历旧数据,补全缺失字段并重新 put; - 索引查询无结果时,不要立即判定“数据不存在”,可 fallback 到主键查或全量扫描(谨慎用);
- 调试阶段用
index.count()和store.count()对比,若差异明显,说明存在大量索引遗漏记录。
特殊字符与 keyPath 限制带来的“伪无效”索引
若原始数据含 @、& 等特殊字符字段名(如 {"user@id": "u123"}),直接用 "user@id" 作 keyPath 会失败(非合法标识符):
- 浏览器不报错,但索引创建静默失败或行为异常;
- 推荐做法是预处理数据结构:统一重命名字段(如转为
user_id),或在写入前做映射转换; - 避免在 keyPath 或索引名中使用非字母数字下划线开头的字符串。

















