代码改变世界

数据库对象之表结构

2011-01-12 21:58  马哈鱼  阅读(501)  评论(0编辑  收藏  举报
     表结构的设计,不外乎三个要素,功能,性能和扩展性。这和程序设计是一个道理。功能上的满足是最根本的,比较简单和容易;我们更多关注的是性能和扩展性。下面就聊聊这两个方
面,
所述内容仅作参考。 
    高性能的表结构应该是精简合理的,数据量应该是尽可能的少。
字段类型和长度应该尽可能真实地反映现实世界中数据的本意,表中的每一条数据都是在描述现实中的一个实体,数据和实体应该是相符的。字段的长度要适当,不能刚刚好,也不能太
长。刚刚好,不能适应数据的变化;太长了,又浪费空间。
    复杂的表结构不仅处理的时候麻烦,有时候对性能也有影响。如果一个表中有多个字段并不是同时存取,可以根据存取特性将其拆分为多个表,这样虽然增加了表间关联,但是表结构的
划分
更加清晰,而且避免了并发操作时的锁现象。反之,在允许的情况下,也可以将多个字段合并为一个字段,前提是不会影响对单个字段的操作。
    允许适当的数据冗余,低级冗余是字段重复,高级冗余是数据派生。冗余的最大好处就是可以减少关联查询,当然也可以利用缓存系统来替代冗余,但是当缓存系统不利的话,冗余字段的
较好的一个选择。
    设计时,应尽量向第三范式靠近,但范式是一个指导性的模式,不能死扣,必要时降低范式标准,以换取性能方面的收益。
    索引是另外一个重要的因素,我们会在稍后探讨。
    硬件环境和系统配置等等因素不在本讨论范围。
    除了性能,可扩展性也是一个关键因素,同时也是容易忽略的,主要包括表的逻辑结构,功能字段的增加和表拆分。
    表的逻辑结构的设计要遵循一个准则,一个表只存储一个实体。如果这个实体中还包含有子实体,或者多个实体共用一个子实体,最好将其独立成一张表,如果以后再增加子实体,也不
会影响以前的表结构。
    需要强调的是,个人比较反对将子实体的字段合并为一个字段再纳入主实体,一来,降低了可读性,表面上看字段减少了,但是却是增加了表结构的复杂性;二来,也增加了处理此字段
度,尤其当子实体拥有不同数据类型的字段时。更重要的是,它违反了数据应该尽量真实地反映现实世界中实体的特性这一原则。
    增加字段,如果是小表或关系很稳定的表,应该不成问题。但是换做是大表的话,有两点一定要记住:在数据访问不是很忙的时候增加字段,并且记得要给当前表加锁。再次反对用合并
字段
作为应对增加字段的手段。一个现实的情况是,很多时候,要增加的字段是不能合并存储的。就算是大表要增加字段,选择好时机和适当的方法还是可以的。
对大表的拆分是提高大表性能的一个有效的方法。水平拆分,如何拆分取决于拆分时所依据的字段的特性。拆分的目的是为了查询时尽可能少的引用表,否则,UNION过多反而会降低水平
拆分所带来的查询性能;垂直分区能够减少查询时扫描的数据,窄表可以使排序和建立索引更加迅速,同时减少表中的索引,从而使记录的insert,update,delete更快。但是太多的表和复杂
表关联会降低系统性能,因此在使用窄表时要综合考虑。