第一范式 1NF
属性不可再分割,符合原子性。
没什么好解释的,地球人都明白
第二范式 2NF
在1NF的基础上:
不允许出现有field部分依赖于主键(或者说依赖于主键的一部分)
官方说法:数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于整组候选关键字。
Allen解释一下:比如一张表是(A, B, C, D),其中(A, B)是主键,如果存在B->C就违反了2NF,因为C只需要主键的一部分就可以被决定了
第三范式 3NF
在2NF的基础上:
不允许出现可传递的依赖关系(transitive dependencies)
官方说法:在第二范式的基础上,数据表中如果不存在非关键字段对关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如果存在"A → B → C"的决定关系,则C传递函数依赖于A
很容易理解,Kiza同学说这是人类的常识。
Boyce-Codd范式 BCNF
在3NF的基础上:
不允许出现有主键的一部分被主键另一部分或者其他部分决定
另一种说法:Left side of every non-trivial FD must contains a key
每个非平凡FD的左边必须有一个主键
BCNF,表中的每个决定因子是候选键。如果只有一个候选键,则3NF和BCNF相同
网友们通常喜欢用的一个例子:
假设仓库管理关系表为StorehouseManage(仓库ID, 存储物品ID, 管理员ID, 数量),且有一个管理员只在一个仓库工作;一个仓库可以存储多种物品。这个数据库表中存在如下决定关系:
(仓库ID, 存储物品ID) →(管理员ID, 数量)
(管理员ID, 存储物品ID) → (仓库ID, 数量)
所以,(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是StorehouseManage的候选关键字,表中的唯一非关键字段为数量,它是符合第三范式的。但是,由于存在如下决定关系:
(仓库ID) → (管理员ID)
(管理员ID) → (仓库ID)
也就是说,(仓库ID, 存储物品ID)这个主键中的仓库ID可以被管理员ID决定,同样(管理员ID, 存储物品ID)中管理员ID也可以被仓库ID决定,所以此表应该拆分。
3NF->BCNF的步骤:
1. 一个表,从所给的FD中,找出一个FD左边没有key的
2. 给这个FD的右边补全属性(field)。
3. 此时得到两个表,一个是第2步中得到的FD中的表,另一个是第2步中FD的所有左边 及 其他所有没有在这个FD中出现的属性组成的表
4. 投影总的FD分别到两个表
如果仍然有表violation,继续分解
例如:
表(Name, Location, Application, Provider, FavAppl)
FD: Name->Location, Name->FavAppl, Application->Provider
Key: Name, Application
1. Name->Location的左边没有key。
2. 将其补充。Name->Location, Name->FavAppl,因此得到表(Name, Location, FavAppl)
3. 一个表是(Name, Location, FavAppl)。另一个表,”第2步中FD的所有左边“是指Name,“其他所有没有在这个FD中出现的属性”是指Application和
Provider。因此第二个表是(Name, Application, Provider)
4. 第二个表中,Application->Provider的左边没有key,继续分解第二个表
最终结果,原表分为了(Name, Location, Provider),(Application, Provider),(Application, Name)
总结:
1NF
| 消除非主属性对码的部分依赖
2NF
| 消除非主属性对码的传递依赖
3NF
| 消除主属性对码的部分和传递依赖
BCNF
http://blog.csdn.net/kkdelta/archive/2009/04/11/4064986.aspx
《Beginning Database Design》 By Wrox