IndexedDB字段迁移需通过版本号递增触发onupgradeneeded,在其中完成结构变更,再于普通事务中渐进式迁移数据。版本号必须为递增正整数,结构操作仅限onupgradeneeded内执行,数据迁移须解耦并分片处理,跨版本升级需用oldVersion小于判断确保兼容。

IndexedDB 本身不提供字段迁移能力,所谓“字段迁移”其实是结构升级 + 数据补写两个阶段的组合动作。关键不在自动改字段,而在用版本号驱动、分阶段可控地完成 schema 变更与数据修正。
版本号递增是触发迁移的前提
每次要新增、删减或重定义字段(比如给用户表加 email 字段),必须提升数据库版本号——不能复用旧值,也不能用小数或字符串。浏览器只在 version 升高时才触发 onupgradeneeded,否则直接走 onsuccess,你的迁移逻辑根本不会执行。
- 首次建库用 v1,后续每次结构变更都 +1:v1 → v2 → v3…
- 传入非正整数(如 0、-1、"2")会导致 open 失败,抛 VersionError 或 InvalidStateError
- 版本不变,哪怕代码里写了 createIndex,也不会生效——对象存储里查不到这个索引
结构变更只能在 onupgradeneeded 中做
建表、删表、建索引、删索引,全部操作必须且只能放在这里。它不是普通回调,而是唯一被授予“schema 操作权限”的上下文。
- 新增字段?不是直接改 objectStore,而是先删旧 store(
deleteObjectStore),再用新 keyPath 或新字段定义重建 - 加索引?先检查
store.indexNames.contains("email_idx"),避免重复建导致 ConstraintError - 删字段?IndexedDB 不支持原地删字段,需在重建 store 时省略该字段,并在后续数据迁移中清理旧值
数据迁移要和结构升级解耦
onupgradeneeded 只适合轻量结构操作。遍历成千上万条记录补字段、转格式、拆字段等,绝不能放进去——会卡主线程,旧版 Safari 超 50ms 就静默 abort 事务。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 结构升级完成后,在普通 readwrite 事务中启动渐进式迁移
- 用独立元数据 store(如
meta)存标记,例如{ migration_v2_done: true },避免重复执行 - 每次处理 50–100 条,用
setTimeout或requestIdleCallback分片,游标 continue 前务必校验transaction.active === true
跨版本跳升要靠 oldVersion 判断
用户可能从 v1 直接打开 v3,中间 v2 的逻辑不能漏掉。别用 oldVersion === 1,改用小于比较:
if (event.oldVersionif (event.oldVersion- 每个块内保持幂等:建 store 前查
db.objectStoreNames.contains,建索引前查store.indexNames.contains
多标签页下必须监听 versionchange
只要另一个标签页还连着旧版本数据库,新页面的 onupgradeneeded 就不会触发——无报错、无提示,是最隐蔽的失败原因。
- 在
onsuccess拿到 db 实例后,立刻写:db.addEventListener('versionchange', () => db.close()) - 配合 UI 提示:“检测到新版本,请刷新页面”,而不是等写失败才响应
- 不要假设旧页已关闭;升级逻辑默认旧连接随时存在

















