onupgradeneeded 是唯一可修改数据库结构的时机,因 IndexedDB 要求结构变更必须与版本号升级强绑定,仅在此事件的 versionchange 事务中允许调用 createObjectStore 等方法,其他时机调用会抛 InvalidStateError。
onupgradeneeded 在 IndexedDB 中,只有数据库版本升级时触发的该时机,才能安全修改数据库结构,例如创建或删除对象存储、索引。
结构变更必须与版本号绑定,这是 IndexedDB 的设计原则。打开数据库时,如果请求版本号高于当前版本,系统就会自动触发 onupgradeneeded,同时传入一个拥有 versionchange 事务的事件对象。此时事务尚未提交且可以读写,因此这是允许调用 createObjectStore、deleteObjectStore、createIndex 等方法的唯一窗口。
若在其他时机调用这些方法,例如普通 readwrite 事务中,系统会直接抛出 InvalidStateError。
indexedDB.open("mydb", 2)
event.oldVersion 以判断升级前所处的版本db.objectStoreNames.contains("storeName") 确认是否已经存在,以免重复创建transaction.objectStore("oldStore").openCursor() 逐项读取数据,再将其写入新结构IndexedDB不允许直接修改已有对象存储的 keyPath 或 autoIncrement 属性;现有 store 无法被修改,只能删除后重新创建。若要调整主键逻辑:
立即学习前端免费学习笔记(深入);
users_v2),再依据新 schema 写入数据db.deleteObjectStore("users"))需要注意,删除 store 会清除全部数据,因此只能在完成迁移后执行。
版本号只能使用大于 0 的整数,不能写成小数或字符串。每次修改结构,即便只增加一个索引,也应提升版本号;建议通过常量或配置集中管理,例如:
const DB_VERSION = 3;不要让硬编码数字分散在多处,以免出现升级遗漏或混乱;升级逻辑同样建议使用 switch(event.oldVersion) 逐步明确每项变更,不要只依靠 if 判断。