云计算百科
云计算领域专业知识百科平台

前端离线数据库数据迁移与备份恢复实战:Dexie.js 版本演进

前端离线数据库数据迁移与备份恢复实战:Dexie.js 版本演进

封面信息图

在本地优先(Local-First)的应用架构中,用户的日记、排版、待办清单全部持久化保存在用户本地的 IndexedDB 数据库中。

随着产品的持续迭代与新版本发布,数据结构发生演进不可避免:

  • 在 V1 版本中,待办项只有一个 completed: boolean;
  • 在 V2 版本中,我们新增了 completedAt: number 与 tags: string[];
  • 在 V3 版本中,我们需要将旧的扁平数据迁移为带有 CRDT 字段级元数据的新结构。

如果处理不当,用户在浏览器刷新打开新版本时,极易发生**“数据库升级失败、甚至旧数据被全盘清空的灾难性事故(Data Loss Disaster)”**。

借助 Dexie.js 的声明式多版本演进管道(Declarative Schema Versioning & Upgrades),我们可以实现**“多版本无缝平滑升级、数据 100% 自动迁移、以及一键 JSON 备份与恢复”**的生产级本地数据库管理体系。

+——————————————————————–+
| Dexie.js 声明式本地数据库版本演进与迁移流水线 |
+——————————————————————–+
| [旧用户本地数据库状态: Version 1 (V1 结构)] |
| └── todos: { id, text, completed, createdAt } |
| |
| [用户打开 V3 新版本网页 -> 触发 Dexie 自动升级管道 (Upgrade Hook)] |
| ├── 升级到 V2: 自动补齐 tags: [] 与 completedAt: 0 |
| └── 升级到 V3: 将字段重构为带有 CRDT 时间戳的高级结构 |
| | |
| [执行原子事务升级: 若中途崩溃自动回滚至 V1, 0 坏库 0 丢数据] |
| |
| [升级成功: 瞬间平滑进入 V3 最新功能界面] |
+——————————————————————–+

1. 声明式版本演进与数据平滑迁移实现

创建 src/db/masterDbMigrations.ts:

import Dexie, { Table } from "dexie";

export class MasterDatabase extends Dexie {
todos!: Table<any, string>;

constructor() {
super("TideMasterStudioDB");

// Version 1 初始结构
this.version(1).stores({
todos: "id, completed, createdAt",
});

// Version 2 升级:新增 tags 索引与字段平滑迁移
this.version(2)
.stores({
todos: "id, completed, createdAt, *tags",
})
.upgrade((tx) => {
// 数据迁移钩子函数:遍历所有旧数据,注入新字段默认值
return tx
.table("todos")
.toCollection()
.modify((todo) => {
if (!todo.tags) todo.tags = [];
if (todo.completed && !todo.completedAt) {
todo.completedAt = todo.createdAt;
}
});
});

// Version 3 升级:新增 orderIndex 浮点排序
this.version(3)
.stores({
todos: "id, completed, orderIndex, createdAt, *tags",
})
.upgrade((tx) => {
let index = 1000;
return tx
.table("todos")
.toCollection()
.modify((todo) => {
todo.orderIndex = index;
index += 1000;
});
});
}
}

2. 本地全量数据一键备份与恢复

export async function exportDatabaseToJson(db: MasterDatabase): Promise<string> {
const allTodos = await db.todos.toArray();
return JSON.stringify({ version: db.verno, todos: allTodos }, null, 2);
}

export async function importDatabaseFromJson(db: MasterDatabase, jsonStr: string) {
const data = JSON.parse(jsonStr);
await db.transaction("rw", db.todos, async () => {
await db.todos.clear();
await db.todos.bulkAdd(data.todos);
});
}

敬畏用户的每一条数据

在本地优先的世界里,用户的数据就是我们最珍贵的信任资产。

用最严谨的迁移工程与防回滚机制,为用户的每一份记录保驾护航。

赞(0)
未经允许不得转载:网硕互联帮助中心 » 前端离线数据库数据迁移与备份恢复实战:Dexie.js 版本演进
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!