V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
FaiChou
V2EX  ›  程序员

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

  •  
  •   FaiChou ·
    FaiChou · 2022-10-28 16:03:23 +08:00 · 2094 次点击
    这是一个创建于 761 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

    第 1 条附言  ·  2022-10-28 16:42:45 +08:00
    谢谢回复, 我是打算开发一个软件, 考虑到了这个问题, 一开始打算做个简单点的功能, 后来可能数据复杂了, 增加一些功能, 如何做向后兼容.
    19 条回复    2022-10-28 21:03:47 +08:00
    zemul
        1
    zemul  
       2022-10-28 16:06:23 +08:00
    加个 version 字段
    imdong
        2
    imdong  
       2022-10-28 16:07:35 +08:00 via iPhone
    文件开头加一个字段 ver ,每次读取都判断一下。

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

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

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

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

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

    然后再做一个记录,记录开始更新时的版本和更新后的版本,读取 API v1 到 v32 的完整更新内容 (这个根据自己业务环境)。
    zhuangzhuang1988
        17
    zhuangzhuang1988  
       2022-10-28 16:50:06 +08:00
    推荐看下这本书 《数据密集型应用系统设计》
    https://book.douban.com/subject/30329536/
    里面有细致的数据兼容讨论
    向下兼容 和 向上兼容(ps: 确实有向上兼容)
    FaiChou
        18
    FaiChou  
    OP
       2022-10-28 16:52:06 +08:00
    @Felldeadbird 顺便问一个额外的问题: 强制升级, 是不是一开始的版本就需要做进去这块逻辑? 比如 v32 开始收费了, 如果老用户一个版本一个版本的升级, 升级到 31 版本就不想升级了.
    Felldeadbird
        19
    Felldeadbird  
       2022-10-28 21:03:47 +08:00
    如果要强制更新,可以一开始就在软件埋入。或者接口类强验证版本。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5513 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 08:41 · PVG 16:41 · LAX 00:41 · JFK 03:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.