indexeddb 通过唯一索引实现本地去重,但需服务端 unique 约束兜底;创建索引用 createindex('key', 'key', {unique: true}),冲突抛 constrainterror;复合唯一需拼接字段;复杂逻辑需事务内手动校验;离线多端同步须依赖服务端冲突处理与前端 uuid 主键+乐观并发控制。

IndexedDB 本身不提供 SQL 那样的 UNIQUE 声明式约束,但可以通过创建唯一索引实现等效效果——这是最直接、最可靠的本地去重机制。
用 createIndex 配置唯一索引
在对象仓库(Object Store)上为某个字段建立唯一索引,浏览器会在插入或更新时自动拦截重复值,并抛出 ConstraintError:
- 调用
objectStore.createIndex('email', 'email', { unique: true })创建索引 - 索引字段值必须全局唯一;若尝试写入已存在的 email,操作立即失败
- 该约束只作用于单个字段,不支持原生复合唯一(如
email + tenantId),需拼接成字符串再建索引 - 错误可被捕获:
request.onerror = e => { if (e.target.error.name === 'ConstraintError') { /* 处理重复 */ } }
复杂场景下手动校验 + 条件写入
当唯一性逻辑涉及多条件(如“软删除状态排除”“时间范围内不可重复”),仅靠索引不够,需在事务中主动控制:
批量分析录音转写,输出多维度拓客报告。触发词:录音分析、总结、音频总结、拜访记录总结。当用户提及「分析录音」「看看录音数据」「最近的录音」「通话记录」且意图为批量统计/分析时触发。仅出现「录音」或「拜访」时需结合上下文,若仅查看单条详情则不触发。
- 开启
readwrite事务,确保读和写原子执行 - 先用
index.get()或store.get()查询是否存在冲突记录 - 根据业务规则决定:拒绝写入、合并数据、或生成新键(如
email + Date.now()) - 所有操作必须在同一事务内完成,否则存在竞态风险
注意离线同步带来的额外冲突
本地唯一性不能覆盖多端并发场景。例如两个设备同时注册同一邮箱,各自本地都“合法”,但同步到服务端会冲突:
- 前端生成 ID 推荐用
crypto.randomUUID()(UUID v4),大幅降低本地重复概率 - 同步时服务端返回
409 Conflict,应携带已有记录 ID,前端据此做合并或提示 - 避免使用时间戳或简单随机数作为主键,极易引发冲突
高频更新时结合版本字段做乐观校验
对可能被多标签页/多窗口同时修改的记录,唯一性常需搭配“不覆盖他人修改”的诉求:
- 每条记录存
version字段(数字或时间戳) - 写入前读取当前 version,提交时检查 version 是否未变(类似 CAS)
- 失败则重试或触发差异对比流程,天然防止后写覆盖前写
真正防重复不能只靠前端。IndexedDB 的唯一索引只保本地一致,关键字段仍需服务端数据库的 UNIQUE 约束兜底,前后端协同才是完整方案。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










