项目设计数据库表时是否需要在表中加备用预留字段?
背景:以前做项目,有用过SSH框架,或者SSM框架,数据库有Oracle,DB2。在开发过程中,有时因数据库设计者未考虑周到,业务实体有一个属性没有对应的字段,因此需要在数据库表加一个字段,又由于此字段要求不可为空,并且在开发阶段,测试数据不多,有时是drop掉了原来的表,增加了一个字段再重新建了一张表。有时一些表,设计表时会在后面加几个类型为varchar的预留字段。
最近和朋友聊到这个问题,就是:为什么要这么做,好处是什么,怎么权衡这个问题。
在遇到这个问题之后引起我思考:预留字段这个通用的做法是否能减少开发阶段由于考虑不周到,或后续维护阶段因为需求变更或者扩展改造而需要增加字段而造成的麻烦?
就此与一些朋友进行了讨论,根据以往的项目经验和设计原则给出了一些解答,以及怎样的设计能确保数据库健壮,可扩展。大家意见不一,以下是正反方的一些意见和看法。
———————————————
正反观点:需要
原因:
1. 持久层的设计,数据库表结构不应轻易变更。因此应设置备用字段。启用备用字段后,只修改代码,在代码中增加注释和并文档说明即可,不需要改动数据库结构,更方便。
2. 如果没有备用字段,如果后期要加字段的话,用add column的方法会改变原先的数据库存储结构,造成数据移动,移动需要时间,而且会移动到其他数据块,add column会影响数据库性能。
3. 对于反方提到的规范问题,只要代码和文档规范是可以避免这样的问题的,即使遇到这样的问题,也比修改表名带来的危险要小,除了要修改代码、存储过程、配置文件中的表名,还要考虑数据的迁移等问题,如此多的改动难免会出现这样那样的问题,因此保证系统的稳定性来看,携带几个扩展字段为了后续使用也无妨。
———————————————
反方观点:不需要
1. 如果要预留字段的话,第一个需要全面考虑的问题,如何评估:
a. 预留多少个字段;
b. 预留什么类型的;
c. 预留的字段不适用怎么办——比如长度/精度不够;
d. 预留的字段允许不允许空值呢;
2. 数据库设置备用字段无法在字段名上体现其意义,不规范,后期维护麻烦。在需要增加字段的时候如果直接add column,也不会有太大工作,但能保证数据库字段的规范。虽然在启用备用字段的时候可以文档说明,但在POJO上对应其属性为attribute1,attribute2等,代码的可读性不强。而且,预留字段全部统一为varchar,也不太合适。
3. 预留字段毕竟是数据库表字段,会占用数据库存储空间。
4. 添加字段出现的性能问题,我之前的项目中一般都是定期对数据库进行数据整理、重组操作。
各方案都有不同的侧重点,最终的你会选择选择哪种方案呢?
——————————————————————————————
CSDN有另一篇博文,地址是:http://blog.csdn.net/iw1210/article/details/44752771,
分析也很不错,给出了相应的解决方案,详细内容如下:
数据库设计误区:备用字段 / 保留字段 / 预留字段
【现象描述】
在数据表中,不仅设计了当前所需要的字段,而且还在其中留出几个字段作为备用。
比方说,我设计了一个人员表(Person),其中已经添加了各种必要的字段,包括姓名(Name)、性别(Sex)、出生年月日(birthday)等等。大功告成之后,我忽然想到,将来系统中应该还会有很多其它与人相关的内容吧,比方说毕业院校,比方说工作单位等等,尽管现在根本不需要填写,以后可能还是会用到的吧。拍脑袋一项,那就加入5个varchar2型的字段,分别叫做Text1、Text2……Text5,然后又想,应该还有一些日期型的字段需要备用,就又建立了三个date型的字段,分别起名叫做date1、date2、date3,……
【原因分析】
大家应该已经看出问题了,在这个数据表中存在大量暂时无用的字段,我们可以称之为备用字段,它们的作用是什么呢?就是以防万一,防备可能的情况。
这似乎可以叫做防患于未然,等到需要的时候,就不需在表中增加新的字段了,而且这样做的话,一个表的数据应该会被存储在相邻的物理空间中,这对于性能也是有好处的。
另外的原因就是,在古老的数据库中,如果改变数据库的定义(包括增加字段、改变字段的类型、删除字段等等),那么其中所有的数据就会丢失,所以这项工作非常麻烦,我们需要先建立临时表,将数据备份出来,然后创建新表,将数据导入其中,最后再删除原来的表。
【问题所在】
这样的做法对于项目会导致很多问题,而且原先想要解决的问题并不一定能够解决,不信的话,请往下看。
问题一:增加大量备用字段,必定会浪费很多空间,尽管其中可能都没有具体的数据,但是仅仅是空字段也会占据一定的空间的。
问题二:由于命名的特点,如果没有完善的文档管理流程,用不了多久(可能也就是两三年),就没有人能够说清楚到底哪个字段代表的是什么意义了。就算有文档管理,这些管理工作也会比较麻烦,而且在每次使用的时候都需要申请,还有可能会出现冲突的情况。
问题三:增加了这些备用字段就真的会够用吗?不一定,因为我们只是每个类型的字段留出几个备用,如果数量超过,或者要使用特殊的、不常用的类型的时候,还是需要增加新的字段。比方说在上述的Person表中,我们要存储照片,那么可能就要增加一个blob类型的photo字段,这在初期设计的时候可不一定会留出这样的备用字段。而且如果没有完善的管理,谁又能说清楚倒底哪个字段已经被使用,哪个字段还可以使用呢?到时候还不是要增加新的字段。
【解决方案】
其实上面的这种设计方式就是一种“过度设计”,我们应该做的就是“按需设计”,在经过详细有效的分析之后,在数据表中只放置必要的字段,而不要留出大量的备用字段。
当需要增加相关的信息的时候,就要具体情况具体分析:
1. 如果数量很少,而且信息的性质与原表密切相关,那么就可以直接在原表上增加字段,并将相关的数据更新进去;
2. 如果数量较大,或者并非是原表对象至关重要的属性,那么就可以新增一个表,然后通过键值连接起来;
3. 对于表的数据的存储位置所导致的性能问题,我们可以通过在特定时间对数据库的数据进行重组来解决,而这项工作对于长期运行的数据库来说,也是需要定期进行的。
------------------------------------------------------
------------------------------------------------------
关于我(个人域名)
我的开源项目集Github
期望和大家 一起学习,一起进步,共勉,O(∩_∩)O谢谢
如果你有任何建议,或想学习的知识,可与我一起讨论交流
欢迎交流问题,可加个人QQ 469580884,
或者,加我的群号 751925591,一起探讨交流问题
不讲虚的,只做实干家
Talk is cheap,show me the code