平时我们做业务需求的时候,难免会碰到有些非常大的改动,大到要修改表结构或者数据结构才能满足,这时候如何能同时兼容老版本的业务与新版本的业务就是一个首要解决问题
1.将老版本数据格式升级到新版本
这是一个很容易想到的解决方案,既然我新版本和老版本数据是冲突的,那我新版本上线前,先把老版本的数据格式刷成新版本支持的格式。
举个实际的例子,数据库有张表中有个type字段,标识了该数据行的数据类型,数据类型如下
type = 'text' content = '{json1}'
type = 'photo' content = '{json2}'
type = 'content' content = '{json3}'
通常我们需要区分type类型,用特定的结构去解析后面的json (一种非常常见的储存方式)。
但是突然有一天,因为某些原因和业务需要,type = ‘text’ 的结构要变化,而且是一种不兼容的变化,这也是开篇所描述的问题,我们要做版本兼容处理。有一种方法就是把老数据的格式全部刷成新的数据格式,并且线上的代码也要修改不能再使用老格式,
这种方案的优点是:没有明显优点
这种方案的缺点是:需要全面排查代码以及不断地思考各个细节点,再加上大量的回归测试成本,而且回退起来很困难,没有后路
2.用version字段进行区分不同版本
在我们的表中提前或者新增version字段,用于标识该数据使用的是哪种版本,然后在我们的业务代码中做区分处理,比如说上面的例子
type = 'text' content = '{json1}' version = 1
type = 'photo' content = '{json2}' version = 1
type = 'text' content = '{json3}' version = 2
应该比较好理解,就不做更多的阐述了,无非就是在我们代码中写很多if else。
这种方案的优点是:对老版本业务影响面最低,回归测试成本低,能回退,有后路
这种方案的缺点是:代码会比较臃肿,因为要处理很多的历史版本,增加理解难度。
3.利用version字段快速修复表数据
有一天,我们突然发现了线上一个潜藏很久的bug,而且这个bug造成了我们表中已经有了非常多的不正常数据,这时候我们可以去选择一条条的修复,但是太过耗费精力。有没有一种办法可以业务无感的把历史数据全部刷新一遍呢?
- 首先第一步,所有查询修改相关的接口(也就是mapper层)增加 version = #{version} 的判断。
- 我们可以事先通过离线数据平台 或者 代码的方式把正确的数据跑出来并写在我们的业务表中 version = 2。
- 通过配置或者接口的方式更改现有的 #{version},相当于切换了数据源。
- 验证没有问题后,就可以删除version = 1的数据了。
这种方案的优点是:改造成本低,刷数据用时少,用户侧无感。
这种方案的缺点是:表中的数据短时间内会膨胀一倍,需要考虑表性能因素。