鸿蒙应用开发实战【98】— 版本迭代数据库升级实战案例本文是「号码助手全栈开发系列」第 98 篇持续更新中…开源社区https://openharmonycrossplatform.csdn.net前言应用上线后数据库结构几乎必然需要随着功能迭代而变更——新增表、新增字段、修改约束。HarmonyOSrelationalStore通过版本号store.version驱动升级流程。本篇以号码助手数据库从 v1 升级到 v2 的过程为例讲解完整的版本升级策略。本篇涵盖upgrade 方法设计、版本号比较逻辑、ALTER TABLE 新增字段、数据迁移与兼容性、降级保护。一、当前数据库版本文件features/data/DatabaseService.etsconstDB_CONFIG:relationalStore.StoreConfig{name:number_assistant.db,securityLevel:relationalStore.SecurityLevel.S2}constDB_VERSION1// 当前版本二、upgrade 方法设计privateasyncupgrade(store:relationalStore.RdbStore,fromVersion:number,toVersion:number):Promisevoid{if(fromVersion1){// v1初始建表4 张表 索引constddls:string[][CREATE TABLE IF NOT EXISTS cards (...),CREATE TABLE IF NOT EXISTS app_bindings (...),CREATE TABLE IF NOT EXISTS sms_candidates (...),CREATE TABLE IF NOT EXISTS sync_meta (...),// 索引CREATE INDEX IF NOT EXISTS idx_ab_card ON app_bindings(card_id),CREATE INDEX IF NOT EXISTS idx_ab_status ON app_bindings(status),CREATE INDEX IF NOT EXISTS idx_ab_name ON app_bindings(app_name)]for(constsqlofddls){awaitstore.executeSql(sql)}hilog.info(0x0000,TAG,建表完成 → v1)}// 后续版本升级在这里追加// if (fromVersion 2) { ... }// if (fromVersion 3) { ... }}三、v1 → v2 升级实战假设 v2 版本需要新增两个字段cards表增加email字段app_bindings表增加expire_at字段3.1 升级代码// DatabaseService.ets — upgrade 方法中追加if(fromVersion2){constalterStatements:string[][// 新增 email 字段允许为空ALTER TABLE cards ADD COLUMN email TEXT NOT NULL DEFAULT ,// 新增过期时间字段ALTER TABLE app_bindings ADD COLUMN expire_at INTEGER NOT NULL DEFAULT 0]for(constsqlofalterStatements){try{awaitstore.executeSql(sql)}catch(e){hilog.error(0x0000,TAG,v2 ALTER TABLE 失败: %{public}s,JSON.stringify(e))thrownewError(数据库升级 v2 失败: JSON.stringify(e))}}hilog.info(0x0000,TAG,升级完成 → v2)}3.2 更新常量constDB_VERSION2// 版本号更新到 2// CardDao 中更新 COLSconstCOLS:string[][id,label,phone_number,carrier,remark,color,sort_order,created_at,updated_at,email// 新增]// 更新 CardEntity 接口exportinterfaceCardEntity{// ...原有字段email?:string// 可选兼容旧数据}四、升级流程时序应用启动 ↓ getRdbStore(context, config) ← 传入最新 DB_VERSION ↓ store.version ! DB_VERSION? ├── 是 → upgrade(store, store.version, DB_VERSION) │ ├── fromVersion 1 → 建表 │ ├── fromVersion 2 → ALTER TABLE │ ├── fromVersion 3 → ... │ └── store.version DB_VERSION │ └── 否 → 直接使用五、最佳实践5.1 增量升级非全量重建// ✅ 正确每个版本增量变更if(fromVersion2){/* ALTER TABLE v1→v2 */}if(fromVersion3){/* ALTER TABLE v2→v3 */}// ❌ 错误每次重建会丢失数据// await store.executeSql(DROP TABLE IF EXISTS cards)// 重新建表...不要这样做5.2 ALTER TABLE 支持的操作操作SQL支持风险等级新增列ALTER TABLE t ADD COLUMN c TYPE✅ 低重命名列ALTER TABLE t RENAME COLUMN old TO new✅ (HarmonyOS 6.1) 中删除列ALTER TABLE t DROP COLUMN c❌ 部分版本不支持 高修改默认值无法直接修改需创建新表迁移 高新增索引CREATE INDEX✅ 低5.3 数据迁移复杂变更当需要合并/拆分列时无法用简单 ALTER TABLE 完成if(fromVersion2){// 1. 创建新表awaitstore.executeSql(CREATE TABLE cards_new ( id INTEGER PRIMARY KEY AUTOINCREMENT, display_name TEXT NOT NULL DEFAULT ))// 2. 迁移数据将 label phone_number 合并为 display_nameawaitstore.executeSql(INSERT INTO cards_new (id, display_name) SELECT id, label || - || phone_number FROM cards)// 3. 删除旧表awaitstore.executeSql(DROP TABLE cards)// 4. 重命名新表awaitstore.executeSql(ALTER TABLE cards_new RENAME TO cards)}5.4 防御性检查// 每次 ALTER TABLE 前检查列是否存在避免重复执行consthasColumnawaitthis.columnExists(store,cards,email)if(!hasColumn){awaitstore.executeSql(ALTER TABLE cards ADD COLUMN email TEXT NOT NULL DEFAULT )}privateasynccolumnExists(store:relationalStore.RdbStore,table:string,columnName:string):Promiseboolean{try{constrsawaitstore.executeSql(PRAGMA table_info(${table}))// 遍历 ResultSet 检查 columnNamewhile(rs.goToNextRow()){if(rs.getString(1)columnName)returntrue}returnfalse}catch{returnfalse}}六、降级保护如果用户安装的是旧版本应用打开新版数据库privateasyncupgrade(...){// 降级保护fromVersion 大于 toVersionif(fromVersiontoVersion){hilog.warn(0x0000,TAG,数据库版本 %{public}d 应用版本 %{public}d降级,fromVersion,toVersion)// 可以选择重新创建或报错thrownewError(数据库不兼容请先升级应用)}// ...}七、版本升级检查清单版本变更内容SQLv1初始建表4 表 3 索引CREATE TABLEv2cards 新增 email、bindings 新增 expire_atALTER TABLE ADD COLUMNv3合并字段示例新建表 INSERT DROP RENAME小结概念要点版本驱动store.version与DB_VERSION比较触发 upgrade增量升级每个版本独立 if 块不破坏旧版本ALTER TABLE主要用 ADD COLUMN复杂变更用建新表 迁移防御性检查列是否存在、降级保护、事务包裹兼容旧数据新字段用 DEFAULT 值新接口参数用可选?如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源开源鸿蒙跨平台社区https://openharmonycrossplatform.csdn.netHarmonyOS relationalStore 开发指南https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/data-persistence-by-rdbHarmonyOS 官方文档https://developer.huawei.com/consumer/cn/doc/HarmonyOS hilog文档https://developer.huawei.com/consumer/cn/doc/harmonyos-references/hilogHarmonyOS testinghttps://developer.huawei.com/consumer/cn/doc/harmonyos-guides/unit-testHarmonyOS 安全与权限https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/permissions-overview