新版本兼容老版本的数据格式有什么方法?

2022-10-28 16:03:23 +08:00
 FaiChou

假如开发一个软件, 软件将用户的一些数据保存在本地, 比如数据如下:

{
  "favorite": [
      {
        "id": 1,
        "name: "sample1"
      },
      {
        "id": 2,
        "name: "sample2"
      },
    ]
}

软件每次打开会读取本地的数据, 转成程序里的数据模型.

经过几个版本的迭代, 加了新的功能, 需要在外层再加一级, 为了不影响老用户的使用, 老用户升级后之前的数据也会继续使用.

像这种情况有什么方法可以兼容? 我想到的是, 在新的版本中打开 app 时候先读取老版本的旧数据, 如果存在则证明是老用户, 将这份数据用一个方法迁移到新的格式中, 然后保存一份新的数据, 再删除旧数据. 除此之外还有其他方法么?

1772 次点击
所在节点    程序员
19 条回复
zemul
2022-10-28 16:06:23 +08:00
加个 version 字段
imdong
2022-10-28 16:07:35 +08:00
文件开头加一个字段 ver ,每次读取都判断一下。

没有这个字段就认为是这个老版本的,以后写文件都要有这个版本字段。
ahhui
2022-10-28 16:10:01 +08:00
新版里,增加一个配置文件的 version 字段,每次更新去更新这个字段值。对于读不出来这个字段的配置文件,可默认按照最初版本操作。每次更新如果配置文件结构变化了,给版本号加 1 个 1 。增加一组类,对旧版本号配置文件进行转换到新配置文件的逻辑,根据文件版本号和你软件里的最新配置版本号比对即可。如果版本号低,执行转换;如果配置文件版本号高,提示用户配置信息是更高版本软件生成的,要求用户升级软件。至于转换就简单了,新增的字段加默认值;对于改名的字段自己做匹配更换。每次软件启动的时候检查配置文件版本号,自动进行升级。
FaiChou
2022-10-28 16:12:26 +08:00
@zemul @imdong

刚才还在编辑写了一大段, 结果你们回复之后保存失败丢失了, 我再补充一下我的问题:

比如微信, 用户群体大, 用户可能用了 n 年前的版本, 如果这位用户直接升级到最新的版本, 里面的数据格式肯定有很大的变化, 比如之前只有视频 /图片 /链接 /语音 /文字, 现在又要加上小游戏 /小程序, 可能数据结构上都发生了变化. 作为微信开发者, 是怎么保证新版本程序可以兼容旧数据的? 是不是只能加很多额外的代码来判断? 比如用 version 字段来标识当前版本, 每一个版本的升级都有相应的方法来转换?
jhdxr
2022-10-28 16:12:39 +08:00
如果是线上已经在用的,那换个文件名吧。。。
FaiChou
2022-10-28 16:15:24 +08:00
接上条, 比如有 10 个版本, 不光要兼容从 1 版本升级到 10 版本的代码, 还要做从 2 版本升级到 7 的代码. 所以版本越多, 版本兼容起来越费劲. 有无更好的办法?
treizeor
2022-10-28 16:18:07 +08:00
直接迁移不行?新版将读到的本地数保存为新的格式
FaiChou
2022-10-28 16:20:08 +08:00
@treizeor 就是直接迁移出现的问题, 看六楼我的回复.
gucheen
2022-10-28 16:20:25 +08:00
@FaiChou 有没有可能,你的兼容应该 1->2 2-> 3->4 ... 9->10 ,逻辑这样去写,这样每次更新只要兼容前一个版本的数据就可以,从低版本到高版本按照版本顺序逐个迁移,一直到最新版本
nmap
2022-10-28 16:21:42 +08:00
json 很简单啊 ,配置只增加,不删除修改,每个版本取自己能识别的配置即可
YepTen
2022-10-28 16:23:58 +08:00
意思你们加了新功能,客户不升级客户端,但还想用新功能?有这好事?
optional
2022-10-28 16:25:28 +08:00
升级是时候对数据进行迁移
FaiChou
2022-10-28 16:26:28 +08:00
@gucheen 对 我的六楼补充有逻辑问题, 应该是 不光要兼容版本 9->版本 10, 还要兼容版本 9 前面的任意版本直接升级到 10 的逻辑, 如果 1->2->3->4...9->10 这样运行的话, 会不会有点.. 毕竟用户可以直接从版本 1 升级到 10 的.
clorischan
2022-10-28 16:33:05 +08:00
@FaiChou #13
用户可以跨版本直接升
但是软件内部对数据的处理还是按照 1>2 2>3 的顺序来依次转换到当前版本
每次软件升级也只用添加兼容上一个版本的转换工具就行.
Felldeadbird
2022-10-28 16:41:47 +08:00
程序打开前检查版本,根据版本内容对需要兼容的数据进行转换 1 次转换。 为了防止出错,转换前备份旧数据。
Felldeadbird
2022-10-28 16:45:32 +08:00
对于跨版本更新,我软件的做法都是自动跳转处理。

例如旧用户 V1 版本。 现在最新是 V32 。

V1 先更新到 V2 ,同时检测 V2 是否存在新版。存在则等 V1->V2 更新完毕,程序继续跳转到下一轮的更新。直到更新到 V32 ,返回当前没有新版本了。 就告诉用户更新成功。

然后再做一个记录,记录开始更新时的版本和更新后的版本,读取 API v1 到 v32 的完整更新内容 (这个根据自己业务环境)。
zhuangzhuang1988
2022-10-28 16:50:06 +08:00
推荐看下这本书 《数据密集型应用系统设计》
https://book.douban.com/subject/30329536/
里面有细致的数据兼容讨论
向下兼容 和 向上兼容(ps: 确实有向上兼容)
FaiChou
2022-10-28 16:52:06 +08:00
@Felldeadbird 顺便问一个额外的问题: 强制升级, 是不是一开始的版本就需要做进去这块逻辑? 比如 v32 开始收费了, 如果老用户一个版本一个版本的升级, 升级到 31 版本就不想升级了.
Felldeadbird
2022-10-28 21:03:47 +08:00
如果要强制更新,可以一开始就在软件埋入。或者接口类强验证版本。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/890739

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX