数据库范式

一、 三范式

主键: 创建表时可以不设置主键 , 但是没有设置主键的表 , 底层会认为所有的键都是主键 ,所以在创建时使用了所有的字段创建索引 , 在查询时索引的存在几乎没有意义 。
复合主键: 两个或两个以上的字段作为评价一条数据记录的唯一性标志 。
第一范式:
强调列的原子性 , 即:列不能分成几列
只要是关系型数据库 , 就自然的遵循第一范式
第二范式:
首先满足第一范式
必须有主键
没有包含在主键中的列必须完全依赖于主键, 而不能只依赖主键的一部分
第三范式:
首先满足第一范式
也属于第二范式的一种情况
任何非主键字段不能依赖于其他非主键字段
三范式是在数据库初期使用(时间换取空间) , 能外键关联就外键关联 , 能不冗余数据设计 , 就不冗余。
但是现在的系统对性能要求高, 对存储要求低(空间换时间)
二、 反范式

但是现在的系统对性能要求高, 对存储要求低(空间换时间) , 所以出现了一套反范式
反范式: 只要违反了第二范式和第三范式 , 就能做到空间换时间 , 获的最大的效率 。

数据库设计时要满足规范化这个道理大家都非常清楚,甚至有数据库的三范式, 好吧, 这有点让我想起了机器人的三定律.但是否数据的规范化程度越高越好呢?这还是由实际需求来决定。

因为规范化越高,那么产生的关系就越多,关系过多的直接结果就是导致表之间的连接操作越频繁,而表之间的连接操作是性能较低的操作,直接影响到査询的速度,所以,对于査询较多的应用,就需要根据实际情况运用逆规范化对数据进行设计,通过逆规范化来提高査询的性能。

例如,移动电话的用户每月都会査询自己的账单,账单信息一般包含用户的名字和本月消费总金额,设想一下,如果用户的姓名和属性信息存放在一个表中,假设表名为A,而用户的 编号和他对应的账单信息存放在另外一张B表中,那么,用户每次查询自己的月账单时,数据库査询时都要进行表连接,因为账单表B中并不包含用户的名字,所以必须通过关联A表取 过来,如果在数据库设计时考虑到这一点,就可以在B表增加一个冗余字段存放用户的名字, 这样在査询账单时就不用再做表关联,可以使査询有更好的性能。

反规范的好处是降低连接操作的需求、降低外码和索引的数目,还可能减少表的数目,相 应带来的问题是可能出现数据的完整性问题。加快查询速度,但会降低修改速度。因此,决定 做反规范时,一定要权衡利弊,仔细分析应用的数据存取需求和实际的性能特点,好的索引和 其他方法经常能够解决性能问题,而不必采用反规范这种方法。

在进行反规范操作之前,要充分考虑数据的存取需求、常用表的大小、一些特殊的计算(例 如合计)、数据的物理存储位置等。常用的反规范技术有增加冗余列、增加派生列、重新组表 和分割表。

增加冗余列:指在多个表中具有相同的列,它常用来在查询时避免连接操作。
增加派生列:指增加的列来自其他表中的数据,由其他表中的数据经过计算生成。增 加的派生列其作用是在查询时减少连接操作,避免使用集函数。
重新组表:指如果许多用户需要查看两个表连接出来的结果数据,则把这两个表重新 组成一个表来减少连接而提高性能.
另外,逆规范技术需要维护数据的完整性。无论使用何种反规范技术,都需要一定的管理 来维护数据的完整性,常用的方法是批处理维护、应用逻辑和触发器。

  1. 批处理维护是指对复制列或派生列的修改积累一定的时间后,运行一批处理作业或存 储过程对复制或派生列进行修改,这只能在对实时性要求不高的情况下使用.
  2. 数据的完整性也可由应用逻辑来实现,这就要求必须在同一事务中对所有涉及的表进 行增、删、改操作.用应用逻辑来实现数据的完整性风险较大,因为同一逻辑必须在所有的应 用中使用和维护,容易遗漏,特别是在需求变化时,不易于维护。
  3. 另一种方式就是使用触发器,对数据的任何修改立即触发对复制列或派生列的相应修 改,触发器是实时的,而且相应的处理逻辑只在一个地方出现,易于维护•一般来说,是解决 这类问题比较好的办法。