1.第三范式
定义
如果关系模式R属于2NF,且每个非主属性都不传递依赖于R的每个关系键,则称R属于第三范式(Third Normal Form),简称3NF,记作R属于3NF。
基本性质:
1.如果R属于3NF,则R也是2NF。
2.如果R属于2NF,则R不一定是3NF。
例如,我们前面由关系模式SCD分解而得到的SD和SC都为2NF,其中,SC属于3NF,但在SD中存在着非主属性MN对主键SNO传递依赖,SD不是3NF。对于SD,应该进一步进行分解,使其转换成3NF。
2.3NF规范化
3NF规范化是指把2NF关系模式通过投影分解转换成3NF关系模式的集合。
和2NF的规范化时遵循的原则相同,即“一事一表”,让一个关系只描述一个实体或者实体间的联系。
举例:将之前的SD表进行再分解,使其满足第三范式
将SD(SN,AGE,DEPT,MN)分解为S(SN,AGE,DEPT)和D(MN),如下图所示
3.第三范式3NF与第二范式2NF相比
(a).数据冗余降低。系主任的名字存储的次数与该系的学生人数无关,只在关系D中存储一次。
(b).不存在插入异常。当一个新系没有学生时,该系的信息可以直接插入到关系D中,而与学生关系S无关。
(c).不存在删除异常。要删除某系的全部学生而仍然保留该系的有关信息时,可以只删除学生关系S中的相关学生记录,而不影响系关系D中的数据。
(d)不存在更新异常。更换系主任时,只需修改关系D中一个相应元组的MN属性值,从而不会出现数据的不一致现象。
SCD规范到3NF后,所存在的异常现象已经全部消失。
4.第三范式3NF的不足
3NF只限制了非主属性对键的依赖关系,而没有限制主属性对键的依赖关系。
如果发生了这种依赖,仍有可能存在数据冗余、插入异常、删除异常和修改异常。
这时,则需对3NF进一步规范化,消除主属性对键的依赖关系,为了解决这种问题,Boyce与Codd共同提出了一个新范式的定义,这就是Boyce-Codd范式,通常简称BCNF或BC范式。它弥补了3NF的不足。
5.BCNF范式
定义 如果关系模式R属于1NF,且所有的函数依赖X→Y(Y ,X),决定因素X都包含了R的一个候选键,则称R属于BC范式(Boyce-Codd Normal Form),记作R属于BCNF。
基本性质
(a).满足BCNF的关系将消除任何属性(主属性或非主属性)对键的部分函数依赖和传递函数依赖。也就是说,如果R属于BCNF,则R也是3NF。
(b)如果R属于3NF,则R不一定是BCNF。
举例:
设关系模式SNC(SNO,SN,CN0,SCORE),其中SNO代表学号,SN代表学生姓名并假设没有重名,CNO代表课程号,SCORE代表成绩。可以判定,SNC有两个候选键(SNO,CNO)和(SN,CNO),其函数依赖如下:
SNO <->SN
(SNO,CNO)→SCORE
(SN,CNO)→SCORE。
唯一的非主属性SCORE对键不存在部分函数依赖,也不存在传递函数依赖。所以SNC属于3NF。
但是,因为SNO <->SN,即决定因素SNO或SN不包含候选键,从另一个角度说,存在着主属性对键的部分函数依赖: (SNO,CNO)-(p)-> SN,(SN,CNO)-(p)->SNO,所以SNC不是BCNF。
分析:
正是存在着这种主属性对键的部分函数依赖关系,造成了关系SNC中存在着较大的数据冗余,学生姓名的存储次数等于该生所选的课程数。从而会引起修改异常。
比如,当要更改某个学生的姓名时,则必须搜索出现该姓名的每个学生记录,并对其姓名逐一修改,这样容易造成数据的不一致问题。
解决这一问题的办法仍然是通过投影分解进一步提高SNC的范式等级,将SNC规范到BCNF。
6.BCNF范式的规范化
BCNF规范化是指把3NF关系模式通过投影分解转换成BCNF关系模式的集合。
还是上面的例子:
将SNC(SNO,SN,CNO,SCORE)规范到BCNF。
分析SNC数据冗余的原因,是因为在这一个关系中存在两个实体,一个为学生实体,属性有SNO、SN;另一个是选课实体,属性有SNO、CNO和SCORE。
根据分解的原则,我们可以将SNC分解成如下两个关系:
S1(SNO,SN),描述学生实体;
S2(SNO,CNO,SCORE),描述学生与课程的联系。
对于S1,有两个候选键SNO和SN,
对于S2,主键为(SNO,CNO)。
在这两个关系中,无论主属性还是非主属性都不存在对键的部分依赖和传递依赖,S1属于BCNF,S2属于BCNF。
7.让我们看一下从1NF到BCNF的转化过程
下图是1NF的函数依赖关系图(存在部分依赖以及传递依赖)
下图是2NF函数依赖关系图(消除了部分依赖但是存在传递依赖)
下图是3NF函数依赖关系图(消除了部分依赖和传递依赖,但是主属性对键存在着部分依赖关系)
下图是BCNF函数依赖关系图(消除了部分依赖和传递依赖,以及主属性对键的部分依赖关系)
8.关系模式的规范化
定义:
一个低一级范式的关系模式,通过模式分解转化为若干个高一级范式的关系模式的集合,这种分解过程叫作关系模式的规范化(Normalization)
目的:
规范化的目的就是使结构合理,消除存储异常,使数据冗余尽量小,便于插入、删除和更新。
原则:
规范化的基本原则就是遵从概念单一化“一事一表”的原则,即一个关系只描述一个实体或者实体间的联系。
规范化的步骤:
(a).对1NF关系进行投影,消除原关系中非主属性对键的部分函数依赖,将1NF关系转换成若干个2NF关系。
(b).对2NF关系进行投影,消除原关系中非主属性对键的传递函数依赖,将2NF关系转换成若干个3NF关系。
(c).对3NF关系进行投影,消除原关系中主属性对键的部分函数依赖和传递函数依赖,也就是说使决定因素都包含一个候选键。得到一组BCNF关系。
规范化的要求:
关系模式的规范化过程是通过对关系模式的投影分解来实现的,但是投影分解方法不是唯一的,不同的投影分解会得到不同的结果。
在这些分解方法中,只有能够保证分解后的关系模式与原关系模式等价的方法才是有意义的。
判断对关系模式的一个分解是否与原关系模式等价可以有三种不同的标准:
1.分解要具有无损连接性。
2.分解要具有函数依赖保持性。
3.分解既要具有无损连接性,又要具有函数依赖保持性。
9.非规范化设计
使用非规范化设计原因:
(a).许多数据库应用强调性能优先
(b).规范化设计有时会导致数据库运行效率的下降
(c).在特殊条件和要求下,适当地降低甚至抛弃关系模式的范式,不再要求一个表只描述一个实体或者实体间的一种联系。其主要目的在于提高数据库的运行效率。
何时进行非规范化处理:
(a).大量频繁的查询过程所涉及的表都需要进行连接;
(b).主要的应用程序在执行时要将表连接起来进行查询;
(c).对数据的计算需要临时表或进行复杂的查询。
非规范化处理的主要技术:
包括增加冗余或派生列,对表进行合并、分割或增加重复表。
10.增加冗余列(用空间换取时间)
增加冗余列是指在多个表中具有相同的列,它常用来在查询时避免连接操作。
举例:
如果经常检索一门课的任课教师姓名,则需要做class和teacher表的连接查询:
select classname,teachername
from class,teacher
where class.teacherno=teacher.teacherno
这样的话就可以在class表中增加一列teacher-name就不需要连接操作了。
增加冗余列可以在查询时避免连接操作,但它需要更多的磁盘空间,同时增加表维护的工作量。
11.增加派生列
增加派生列指增加的列来自其它表中的数据,由它们计算生成。
它的作用是在查询时减少连接操作,避免使用集函数。派生列也具有与冗余列同样的缺点。
12.重新组表
重新组表指如果许多用户需要查看两个表连接出来的结果数据,则把这两个表重新组成一个表来减少连接而提高性能。
举例:
用户经常需要同时查看课程号,课程名称,任课教师号,任课教师姓名,则可把表class(classno,classname,teacherno)和表teacher(teacherno,teachername)合并成一个表class(classno,classname,teacherno,teachername)。
这种方法可以提高性能,但需要更多的磁盘空间,同时也损失了数据在概念上的独立性。
13.对表进行分割
表分割有两种方式:
水平分割
垂直分割
水平分割:根据一列或多列数据的值把数据行放到两个独立的表中。
水平分割的使用:
(a).表很大,分割后可以降低在查询时需要读的数据和索引的页数,同时也降低了索引的层数,提高查询速度。
(b).表中的数据本来就有独立性,例如表中分别记录各个地区的数据或不同时期的数据,特别是有些数据常用,而另外一些数据不常用。
(c).需要把数据存放到多个介质上。
举例:
法规表law就可以分成两个表active-law和inactive-law。active-law表中的内容是正生效的法规,是经常使用的,而inactive-law表则使已经作废的法规,不常被查询。
水平分割会给应用增加复杂度,它通常在查询时需要多个表名,查询所有数据需要union操作。在许多数据库应用中,这种复杂性会超过它带来的优点。
垂直分割:把主键和一些列放到一个表,然后把主键和另外的列放到另一个表中
垂直分割的使用:
如果一个表中某些列常用,而另外一些列不常用,则可以采用垂直分割加快查询速度。其缺点是需要管理冗余列,查询所有数据需要join操作。
14.非规范化设计总结
主要优点:
(a).减少了查询操作所需的连接
(b).减少了外部键和索引的数量
(c).可以预先进行统计计算,提高了查询时的响应速度
主要问题:
(a).增加了数据冗余
(b).影响数据库的完整性
(c).降低了数据更新的速度
(d)增加了存储表所占用的物理空间