1. 定义
当下面性质成立时,一个数据库模式中的表T及函数依赖集F被称为符合Boyce-Codd范式(BCNF):任何F可推导出的函数依赖X->A都在T中,这里A是不在X中的单一属性,X必须是T的一个超键。当一个数据库模式包含的所有表都符合BCNF时,这个数据库被称为符合BCNF.
2. 说明
BCNF是比第三范式更严格一个范式。它要求关系模型中所有的属性(包括主属性和非主属性)都不传递依赖于任何候选关键字。也就是说,当关系型表中功能上互相依赖的那些列的每一列都是一个候选关键字时候,该满足BCNF。
BCNF实际上是在第三范式的基础上,进一步消除了主属性的传递依赖。
3. 举例
有这样一个配件管理表WPE(WNO,PNO,ENO,QNT),其中WNO表示仓库号,PNO表示配件号,ENO表示职工号,QNT表示数量。
有以下约束要求:
(1) 一个仓库有多名职工;
(2) 一个职工仅在一个仓库工作;
(3) 每个仓库里一种型号的配件由专人负责,但一个人可以管理几种配件;
(4) 同一种型号的配件可以分放在几个仓库中。
分析表中的函数依赖关系,可以得到:
(1) ENO->WNO;
(2) (WNO,PNO)->QNT
(3) (WNO,PNO)->ENO
(4) (ENO,PNO)->QNT
可以看到,候选键有:(ENO,PNO);(WNO,PNO)。所以,ENO,PNO,WNO均为主属性,QNT为非主属性。显然,非主属性是直接依赖于候选键的。所以此表满足第三范式。
而我们观察一下主属性:(WNO,PNO)->ENO;ENO->WNO。显然WNO对于候选键(WNO,PNO)存在传递依赖,所以不符合BCNF.
解决这个问题的办法是分拆为两个表:管理表EP(ENO,PNO,QNT);工作表EW(ENO,WNO)。但这样做会导致函数依赖(WNO,PNO)->ENO丢失。
4. 应用
虽然,不满足BCNF,也会导致一些冗余和一致性的问题。但是,将表分解成满足BCNF的表又可能丢失一些函数依赖。所以,一般情况下不会强制要求关系表要满足BCNF。
五. 第四范式(4NF)
1. 定义
第四范式需要满足以下要求:
(1) 必须满足第三范式
(2) 表中不能包含一个实体的两个或多个互相独立的多值因子。
2. 说明
显然,第四范式也是一个比第三范式严格的范式。
第四范式的意思是:当一个表中的非主属性互相独立时(3NF),这些非主属性不应该有多值。若有多值就违反了第四范式。定义比较抽象,可以参照下面的例子理解。
3. 举例
有这样一个用户联系方式表TELEPHONE(CUSTOMERID,PHONE,CELL)。 CUSTOMERID为用户ID,PHONE为用户的固定电话,CELL为用户的移动电话。
本来,这是一个非常简单的第3范式表。主键为CUSTOMERID,不存在传递依赖。但在某些情况下,这样的表还是不合理的。比如说,用户有两个固定电话,两个移动电话。这时,表的具体表示如下:
CUSTOMERID |
PHONE |
CELL |
1000 |
8828-1234 |
149088888888 |
1000 |
8838-1234 |
149099999999 |
由于PHONE和CELL是互相独立的,而有些用户又有两个和多个值。这时此表就违反第四范式。
在这种情况下,此表的设计就会带来很多维护上的麻烦。例如,如果用户放弃第一行的固定电话和第二行的移动电话,那么这两行会合并吗?等等
解决问题的方法为,设计一个新表NEW_PHONE(CUSTOMERID,NUMBER,TYPE).这样就可以对每个用户处理不同类型的多个电话号码,而不会违反第四范式。
4. 应用
显然,第四范式的应用范围比较小,因为只有在某些特殊情况下,要考虑将表规范到第四范式。所以在实际应用中,一般不要求表满足第四范式。
六. 第五范式(5NF)
1. 定义
第五范式有以下要求:
(1) 必须满足第四范式
(2) 表必须可以分解为较小的表,除非那些表在逻辑上拥有与原始表相同的主键。
2. 说明
第五范式是在第四范式的基础上做的进一步规范化。
第四范式处理的是相互独立的多值情况,而第五范式则处理相互依赖的多值情况。
3. 举例
有一个销售信息表SALES(SALEPERSON,VENDOR,PRODUCT)。SALEPERSON代表销售人员,VENDOR代表供和商,PRODUCT则代表产品。
在某些情况下,这个表中会产生一些冗余。可以将表分解为PERSON_VENDOR表(SALEPERSON,VENDOR);PERSON_PRODUCT表(SALEPERSON,PRODUCT);VENDOR_PRODICT表(VENDOR,PRODUCT)。
4. 应用
第五范式的应用就更少了,很多时候,我认为分解为第五范式是完全没必要的。可能在某些情况下会有意义吧。不懂。。。
总结:
总之,规范化的过程就是在数据库表设计时移除数据冗余的过程。随着规范化的进行,数据冗余越来越少,但数据库的效率也越来越低。
这就要求你在数据库设计中,能结合实际应用的性能要求,规范到合适的范式。一般情况下,如何性能允许的话,都要求规范到第三范式的。
===================================================
例子:STC(Sid,Tid,Cid) 学生选课m:n,老师授课m:1,
有以下函数依赖:(Sid,Cid)->Tid;(Sid,Tid)->Cid;Tid->Cid
这个表不符合BCNF但符合第三范式。
改为:ST(Sid,Tid);TC(Tid,Cid)。现在就符合BCNF了。
3NF->BCNF 需要消除主属性对键的部分和传递函数依赖。