关系型数据库设计

对于一般的依赖于关系型数据库的项目来说,数据库的设计决定了软件项目的复杂度,以及性能等方面。最近很多项目的经验都是感觉被数据库的设计给坑了,这里面有自己设计的,也有别人设计的。总之数据库的设计非常重要,所以不得不对它有所思考。

说起数据库设计,首先不免想到三大范式,然而三大范式并不完全涵盖数据库设计的各个方面。三大范式只说了一件事,就是表的列要有充分的原子性,要够单纯。第一范式说列必须是原子的;第二范式说列必须依赖于完整的主键而非部分主键,也可以说第二范式是对主键的要求;第三范式说列不能依赖于非主键的列,也就是说一张表中的每个列都应该是跟主键完全相关的,不相关的数据不能出现在同一张表中。也可以这样理解,三大范式规定了每个表都是单纯的,表中的列都是紧耦合的。

三大范式没有说什么?表与表之间的关系应该如何设计?原子性的粒度应该多大?

不难理解这两个问题跟实际的应用相关,我们的应用可能是读多于写的,也可能是写多于读的,也可能读写都很多。可能对性能要求很高,实时性要求很高。所以数据库的表结构设计不光要考虑到数据建模的问题,还要考虑到实际的应用,要怎么用很关键。比如可能只是用作报表数据,也可能是某实时性要求很高的平台的数据中心。表的结构应该有利于应用。

应用的本质可以概括为两方面,事务性的和分析性的。事务性的应用对数据的增删改操作较多,而分析性的应用对表单的查询可能比较关注。在设计数据库的时候就要按需进行设计了。

表与表之间的关系应该如何设计呢?如果每张表都是独立的,互相之间没有关系,那样最好,查询的性能也好,事务性也好。但是这是不可能的,表与表之间总要有关系,一张表可能和多张表有关系。一张表关联的表越多结构就越复杂,这个时候应该考虑重新设计。比如一个项目,有项目的进度,项目的负责人,项目的状态,项目的实施地点,这些字段都可以作为单独的表,而这张项目表就保存了很多跟其他表的关联--外键。这张表在查询的时候需要做很多的关联查询。如果是查询比较多的应用,应该考虑冗余字段,让他违反三大范式,但是有利于查询。但是如果要更新的话可能需要更新两种表,这就是违反范式的坏处。如果确定相关的字段很少改动这样的冗余是很有必要的。

表显然不是越多越好,表越多,关联也就越多。假如有一张用户表,有一张房屋的表,如何表达用户与房屋之间的关系呢?独立建一张用户房屋表可以完美的表现这个关系。但是为此却多出一张表来,我们要查询房屋的信息需要关联查询三张表。如果一个房屋只属于一个人,那么简单的在房屋表中加一列屋主的id就可以了。只有多对多的关系才考虑重新建一张表。因为只有那样才能表现多对多的关系。一对多的关系尽量避免增加表。

一些标准化的数据需要建表,为了所有引用到的地方都引用到唯一的标准,比如项目的状态,在项目表中使用,也可能在其他表中使用。但是这样带来的问题是为了很少的数据建立了一张表,造成了一次表的关联。

尽量遵守第三范式,与主键无关的列不要放在同一张表中。当然有时候是冗余字段,这种情况可以视情况允许。我这里说的是不能把不同类型的数据糅合在一张表里,比如为了能让这张表即可以被A项目用,又可以被B项目用就糅合两个项目的数据在一起,虽然他们有一些相同的字段,但是还有一些不同的字段,更甚者他们可能主键不同。千万不要这样设计,还是把他们分成两张表比较好,这样的复用不要也罢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值