0,相关定义
关于候选键,主键,超键可以参考:
http://blog.sina.com.cn/s/blog_6d677b680100sveh.html
主属性:包含在任何一个候选键中的属性
非主属性:不包含在任何候选键中的属性
1,第一范式(1NF)
定义:关系型数据库中每个字段都只能放单一值,且每笔记录能用唯一主键来区别。
第一范式消除了字段有多个值的情况,是关系型数据库的基本要求。
但只满足第一范式的话会造成数据表臃肿。
这就需要第二范式加以约束。
2,第二范式(2NF)
定义:在满足第一范式的前提下,非主属性均完全函数依赖于主属性(主键)。
什么是完全函数依赖呢?
举个例子:我们把属性1,2决定属性3记为:(1,2)—> 3。 也就是说3函数依赖于1,2。
如果1单独就可以决定3的值,那么我们就说3部分函数依赖于1。
反之,如果1,2只有共同作用才能决定3,那么我们才是3完全函数依赖于1,2。
显然,当主属性只有一个的时候,必然满足第二范式。
第二范式消除了非主属性对主属性的部分函数依赖,保证了主属性的精简性,很大程度上减轻了表的冗余。
但是非主属性之间也可能存在函数依赖关系,这就需要第三范式来约束。
3,第三范式(3NF, nothing but the key)
定义:在满足第二范式的前提下,非主属性均只与主属性有相关性。也就是说,非主属性之间没有任何依赖关系。
也有人说,第三范式消除了非主属性对主属性的传递函数依赖。事实上,只要非主属性间没有依赖关系,自然就没有对主属性的传递依赖。
所以两种说法是等价的。
第三范式进一步精简了表,减少了数据冗余。一般来说数据库的设计做到第三范式就足够了。
4,BCNF
我们考虑这样一个问题。2NF,3NF消除了非主属性对主属性的部分依赖和传递依赖。但如果主属性对非主属性有依赖关系怎么办呢?
也就是说如果主属性A依赖于非主属性B,也即是 B -> A,那么前面三个范式均无法解决。这就要求我们提出一条更严格的范式。这就是BCNF。
BCNF是第三范式(3NF)的一个子集,也有人把它称为3.5NF。
BCNF要求:如果 B -> A , 那么B要么包含A,要么是超键。
这也就排除了主属性对非主属性的依赖,以及主属性对候选码的部分依赖。
也就是说BCNF要求在关系数据库中起决定作用的集合必定是候选码集的超集。
满足BCNF范式的关系必定满足以下几点:
- 所有非主属性都完全函数依赖于每个候选码
- 所有主属性都完全函数依赖于每个不包含它的候选码
- 没有任何属性完全函数依赖于非候选码的任何一组属性
5. 其他
具体例子可以参考:
https://www.zhihu.com/question/24696366
6. 参考文献
https://zh.wikipedia.org/wiki/%E7%AC%AC%E4%B8%80%E6%AD%A3%E8%A6%8F%E5%8C%96
https://zh.wikipedia.org/wiki/%E7%AC%AC%E4%BA%8C%E6%AD%A3%E8%A6%8F%E5%8C%96
https://zh.wikipedia.org/wiki/%E7%AC%AC%E4%B8%89%E6%AD%A3%E8%A6%8F%E5%8C%96
https://zh.wikipedia.org/w/index.php?title=BC%E6%AD%A3%E8%A6%8F%E5%8C%96&redirect=no
https://en.wikipedia.org/wiki/Boyce%E2%80%93Codd_normal_form
https://www.zhihu.com/question/24696366