数据表的设计原则:
()不应针对整个系统进行数据库设计而应该根据系统架构中的组件划分针对每个组件所处理的业务进行组件单元的数据库设计;不同组件间所对应的数据库表之间的关联应尽可能减少如果不同组件间的表需要外键关联也尽量不要创建外键关联而只是记录关联表的一个主键确保组件对应的表之间的独立性为系统或表结构的重构提供可能性
()采用领域模型驱动的方式和自顶向下的思路进行数据库设计首先分析系统业务根据职责定义对象对象要符合封装的特性确保与职责相关的数据项被定义在一个对象之内这些数据项能够完整描述该职责不会出现职责描述缺失并且一个对象有且只有一项职责如果一个对象要负责两个或两个以上的职责应进行分拆
()根据建立的领域模型进行数据库表的映射此时应参考数据库设计第二范式一个表中的所有非关键字属性都依赖于整个关键字关键字可以是一个属性也可以是多个属性的集合不论那种方式都应确保关键字能够保证唯一性在确定关键字时应保证关键字不会参与业务且不会出现更新异常这时最优解决方案为采用一个自增数值型属性或一个随机字符串作为表的关键字
()由于第一点所述的领域模型驱动的方式设计数据库表结构领域模型中的每一个对象只有一项职责所以对象中的数据项不存在传递依赖所以这种思路的数据库表结构设计从一开始即满足第三范式一个表应满足第二范式且属性间不存在传递依赖
()同样由于对象职责的单一性以及对象之间的关系反映的是业务逻辑之间的关系所以在领域模型中的对象存在主对象和从对象之分从对象是从N或NN的角度进一步主对象的业务逻辑所以从对象及对象关系映射为的表及表关联关系不存在删除和插入异常
()在映射后得出的数据库表结构中应再根据第四范式进行进一步修改确保不存在多值依赖这时应根据反向工程的思路反馈给领域模型如果表结构中存在多值依赖则证明领域模型中的对象具有至少两个以上的职责应根据第一条进行设计修正第四范式一个表如果满足BCNF不应存在多值依赖
()在经过分析后确认所有的表都满足二三四范式的情况下表和表之间的关联尽量采用弱关联以便于对表字段和表结构的调整和重构并且我认为数据库中的表是用来持久化一个对象实例在特定时间及特定条件下的状态的只是一个存储介质所以表和表之间也不应用强关联来表述业务(数据间的一致性)这一职责应由系统的逻辑层来保证这种方式也确保了系统对于不正确数据(髒数据)的兼容性当然从整个系统的角度来说我们还是要尽最大努力确保系统不会产生髒数据单从另一个角度来说髒数据的产生在一定程度上也是不可避免的我们也要保证系统对这种情况的容错性这是一个折中的方案
()应针对所有表的主键和外键建立索引有针对性的(针对一些大数据量和常用检索方式)建立组合属性的索引提高检索效率虽然建立索引会消耗部分系统资源但比较起在检索时搜索整张表中的数据尤其时表中的数据量较大时所带来的性能影响以及无索引时的排序操作所带来的性能影响这种方式仍然是值得提倡的
()尽量少采用存储过程目前已经有很多技术可以替代存储过程的功能如对象/关系映射等将数据一致性的保证放在数据库中无论对于版本控制开发和部署以及数据库的迁移都会带来很大的影响但不可否认存储过程具有性能上的优势所以当系统可使用的硬件不会得到提升而性能又是非常重要的质量属性时可经过平衡考虑选用存储过程
()当处理表间的关联约束所付出的代价(常常是使用性上的代价)超过了保证不会出现修改删除更改异常所付出的代价并且数据冗余也不是主要的问题时表设计可以不符合四个范式四个范式确保了不会出现异常但也可能由此导致过于纯洁的设计使得表结构难于使用所以在设计时需要进行综合判断但首先确保符合四个范式然后再进行精化修正是刚刚进入数据库设计领域时可以采用的最好办法
()设计出的表要具有较好的使用性主要体现在查询时是否需要关联多张表且还需使用复杂的SQL技巧
()设计出的表要尽可能减少数据冗余确保数据的准确性有效的控制冗余有助于提高数据库的性能