以前聊过Mysql以key-val存储、正常存储的区别,在此基础上,我们再聊一下具体的业务场景。
如果一个业务,不断的有新的字段增加,新增加的字段要参与到增删改查功能中,底层需要怎么设计?
我不建议把所有的数据全部打平为key-val结构,虽然扩展方便,但带来的问题也很多。
场景判断
其实需要先判断一下真实的情况
1.字段增加的频率
- 如果几个月增加一次,其实完全可以放主表,但是需要优化增删改查的逻辑,实现只需要很少的改动或者只是配置就能实现增加字段的效果。这样只需要提DDL工单、配置一下(理想情况)就行。
2.增加的字段是强依赖还是弱依赖?这对扩展的要求是不一样的。
- 强依赖:如果使用扩展方案,最好使用事务。如订单金额这种,必须和订单强一致
- 弱依赖:这种可以使用消息方案,如商品上的标签、订单上的备注等。这种可以使用打标系统,辅助消息补偿
选型
一般而言我们都需要有一张主表(毕竟需求是慢慢变化的),根据不同场景需要使用不同的扩展方案。
主表方案 | 扩展表方案 | |||
---|---|---|---|---|
思路一:在主表表添加字段 | 思路二:扩展字段添加key | 思路三:纯扩展表 - 事务 | 思路四:建打标系统 - 消息补偿 | |
优点 | 1. 清晰:字段明确,方便维护2.独立:不会影响bot的其他配置3.数据一致性:天生一致性 | 1.开发成本低:无需改库、无需修改每个接口2.扩展性强:可以方便的添加新的功能3.数据一致性:天生一致性 | 1.扩展性强:能够在不改动主表情况下增加字段2.数据一致性:可以使用事务保证一致性3.能力全:方便按照各种维度管理主表信息(版本、全局) | 1.扩展性强:服务端改动小,开发成本低,新增字段仅需配置新的key。将bot的部分属性打平存储到另一个库表,不影响bot主表信息2.能力全:方便按照各种维度管理主表信息(版本、全局) |
缺点 | 1.扩展性差:可能需要在多个表表添加字段;需要修改增删改查接口 | 1.不清晰:无法明确知道包含哪些功能2.不独立:扩展字段经存储了很多配置,误操作的更新操作可能影响扩展字段里的其它配置 | 1. 维护成本高:事务保证强一致性;查询复杂2.字段浪费:必须有主键、更新时间等,而且字段必须是varchar3.排序、筛选:实现复杂 | 1.无法保证强一致性:可能出现数据不一致问题(最终一致性)2.维护成本高:tag表的版本维护,版本回退功能复杂3.管理成本高:需要判断使用该给功能的字段都无需强一致性4.字段浪费:必须有主键、更新时间等,而且字段必须是varchar5.排序、筛选:实现复杂 |
可以看到,一旦使用扩展方案,整个的维护复杂度是要提升很多的。
另外,如果真的是用扩展方案,因为里面的value都是json,为了方便调用方,可以提供配套的SDK,改SDK可以分析扩展里的数据,帮助调用方快速获得信息,而不必理解json结构。