indexeddb 通过整数版本号和 upgradeneeded 事件实现可靠 schema 迁移,版本必须递增、迁移逻辑须幂等且仅在该事件中执行,web sql 已废弃不应使用。

HTML5 的 Web SQL Database(已废弃)和 IndexedDB 都不直接提供“数据库版本号管理”的自动机制,所谓“版本混乱”本质是开发者对 schema 迁移逻辑缺失或随意处理 导致的。真正需要规范的是迁移过程本身,而非版本号格式。
用显式 upgradeNeeded 事件驱动 schema 变更
IndexedDB 的 open() 方法第二个参数为 version,但仅当传入值 > 当前数据库版本时才触发 upgradeneeded 事件——这是唯一安全执行结构变更的时机。
- 永远不要在
success或error回调中手动创建/删除 objectStore - 所有表结构增删、索引添加、字段迁移都必须写在
upgradeneeded处理函数内 - 若需从 v1 升级到 v3,且用户当前是 v1,则该事件会依次触发 v1→v2、v2→v3 的完整升级路径(只要代码里按顺序判断并执行)
版本号采用递增整数,禁止跳变或回退
IndexedDB 内部只接受非负整数作为版本,语义上代表 schema 的演进序号,不是语义化版本(如 1.2.0)。
- 初始打开用
indexedDB.open('mydb', 1),后续每次结构变更都 +1 - 避免使用 Date 时间戳、哈希值或随机数作版本号——它们无法表达先后依赖关系
- 若团队协作,建议在项目文档中维护一张 version → change log 映射表,例如:
v1:用户表;v2:增加订单表+外键模拟;v3:添加订单状态索引
迁移逻辑必须幂等且可中断恢复
用户可能在升级中途刷新页面,或设备断电。因此每个版本的升级步骤应具备“重复执行不报错、不丢数据”特性。
- 检查 objectStore 是否已存在再创建:
if (!db.objectStoreNames.contains('users')) { db.createObjectStore('users', {keyPath: 'id'}); } - 字段迁移时先读旧数据、转换、写新结构,再删旧 store(如需);避免“全量覆盖”式操作
- 对大表做迁移,考虑分批处理(用 cursor + setTimeout),并在 IDB 中记录当前迁移进度(如存一个
migration_v2_progresskey)
弃用 Web SQL,不引入额外版本抽象层
Web SQL 已被所有现代浏览器废弃(Chrome 120+ 完全移除),其 openDatabase 的 version 参数从未被用于强制迁移,仅作标识用途,极易误用。
- 不要基于 Web SQL 封装“自动版本比对+SQL执行”工具——这只会掩盖设计缺陷
- 不要为 IndexedDB 包装一层“语义化版本管理器”,比如把 v1.2.0 解析成 1020 去调 open()——徒增复杂度且无实际收益
- 聚焦在清晰的
upgradeneeded分支逻辑 + 整数版本递进 + 幂等操作,就是最轻量可靠的方案
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










