作为架构师或者开发人员,面对业务方提出的数据结构变化的需求总是很头痛的,今天让你加个描述字段,明天让你再加个什么标记,后天又需要增加一个时间戳,千奇百怪,层出不穷,实在头痛。但是,我们不能随意的指责什么,因为业务在发展,而且我们不能也不应该因为技术或者实现的原因去否决一些业务变化,毕竟技术是什么?真正产生价值的还是业务!
那,在实践中,我们如何面对这种无法避免而且往往很难预期的数据结构变化呢?
第一种方法,预留字段
既然很难加字段,就预先留好一些备用,比如加上10个Date,20个VARCHAR,10个Number之类的,虽然看起来猥琐了点,而且没那么灵活,其实还是很实用的,生产中也有不少人使用,不过因为预先留的字段一般是没什么含义的,需要有额外的信息来描述他,COL1是什么含义,COL2是什么含义,演变到后来有的就干脆更极端,所有字段都是无意义的名字,全靠外部的meta信息来描述,这种用法据我所知至少有三个地方在使用,两个是我亲自听到设计者描述的,另一个是别人告诉我的
不管怎样,预留字段的方式还是很解决很多问题的,而且基本不影响性能,除了额外的meta信息描述外,也没有其他的负担。
第二种方法,使用复杂字段
这个应用的场景不是很多,在某些特殊要求下还是很有用的,比如,某个业务实体(某张表),有一些标记位,都是true/false之类的标记,可以理解为这个实体的一些属性,经常需要添加,这种情况,在生产中我们使用过用一个数字,按位来表示这些标记的,比如第三位表示他是不是付费用户,第四位表示他是合作方来的用户还是自己注册的,等等。还有一种情况,需要更复杂的属性列表,属性个数经常变,可以考虑使用一个文本字段,保存结构化的数据,比如自己定义一个xml的格式
使用复杂字段的好处就在于比较灵活,同一类型的数据可以放在一起(实际上相当于把应该是一个关联表的数据放一个字段里了),操作的性能也不错,但是复杂字段里面的内容查询比较困难
还有一种方法,将数据的存储和索引(需要查询的内容)分开存放,相当于主表就一个key-value,value就是一个大的xml(或者其他的一坨),把需要查询的字段放到其他单独的表里去,可以参考friendfeed如何使用mysql,这是一个实际的例子。实际上在02-03年的时候,老是面对这样的问题,我就在考虑这样的方案,我当初的想法是,用bdb来存储数据(就是那个key-value)了,要检索的数据放到lucene里去,但是因为那个系统对实时性的要求而没法实施,但是并不是每个系统都要求这么实时的,在有些地方还是可以考虑使用的
另外,还有column based db,也可以很好的解决这个问题,实际上他就本本回避了加字段的问题,不过现在似乎没有性能很好的实现
上面这些方案的,都有局限性,选用的时候要看场景的,而且有可能今天作出的决定是对的,过了两年就变的不适合了,事情总是在变化的嘛...