在设计数据库时,我们往往依照数据库的范式降低数据间的冗余度,但是范式就像是把双刃剑,尤其是在大数据时代,有效的增加数据的冗余度,还可以提高数据的访问效率。但是处在初级设计阶段就需要对数据库范式有足够的理解,设计出更加规范的数据库,具体来说常见的范式主要为以下部分:
1NF
简单的说就是该属性不可再分,在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
问题:例如地址可以拆分成城市、地区、街道等部分,不可以作为一个属性。
解决:将地址拆分,设置多个属性。
2NF
每个表中的非主属性完全依赖于码。数据库表中不存在非关键字段对任一候选键的部分函数依赖,也即所有非关键字 段都完全依赖于任意一组候选关键字。
2NF的违例只会出现在候选键由超过一个字段构成的表中,因为对单关键字字段不存在部分依赖问题。
问题:(学号,课程号)这个表中的码被“学生名字”部分函数依赖。即包含有学号→学生名字这种依赖关系。不符合2NF
解决:将部分函数依赖的部分码和依赖这些码的属性拿出来单独成表,在原表中用外键代替以前的多个属性。
3NF
消除非主属性之间的依赖关系,只保留非主属性与码的依赖关系。出现传递依赖A->B->C,即主键A可以确定出某一非关键字段B,而B又可以确定出C,这意味着C依赖于一个非关键字段B。因此第三范式又可描述为:表中不存在可以确定其他非关键字的非键字段
问题:出现传递依赖A->B->C,即主键A可以确定出某一非关键字段B,而B又可以确定出C,这意味着C依赖于一个非关键字段B。因此第三范式又可描述为:表中不存在可以确定其他非关键字的非键字段
解决:将这个非主属性与其依赖的码都拿出来单独建表,并设置被依赖的属性为主键,在原表中则用外键表示。
BCNF
问题:学号,学生名字,学生QQ。我们设置学号作主键,但是学生QQ、学号这两个都是候选键,一张表中有多个候选键,不符合BC范式。
解决:保留一个候选键作为主键,拿出其他的候选键单独成表,将原表中的主键放入该表中。在原表中不显示这个拿出来的候选键,从而 保证每个表中只有1个候选键。
范式关系
-- 消除决定因素非码的非平凡函数依赖
| 1NF
| ↓ 消除非主属性对码的部分函数依赖
| 2NF
| ↓ 消除非主属性对码的传递函数依赖
| 3NF
| ↓ 消除主属性对码的部分和传递函数依赖
| BCNF
| ↓ 消除非平凡且非函数依赖的多值依赖
| 4NF
| ↓消除不是由候选码所蕴含的连接依赖
| 5NF
总结
- 1NF: 字段是最小的的单元不可再分
- 2NF:满足1NF,表中的字段必须完全依赖于全部主键而非部分主键 (一般我们都会做到)
- 3NF:满足2NF,非主键外的所有字段必须互不依赖
- BCNF:在满足第二第三范式的情况下,主属性内部也不能部分或传递依赖。判断方法:箭头左边的必须是候选码,不是候选码的就不是BC范式。
- 4NF: 没有多值依赖
参考资料
- 范式间的区别(具体例子)http://www.cnblogs.com/winlinglin/archive/2008/11/19/1336337.html
- [学习笔记]数据库设计三大范式与BCNF,学习笔记http://www.cnblogs.com/ybwang/archive/2010/06/04/1751279.html
- 解释一下关系数据库的第一第二第三范式?https://www.zhihu.com/question/24696366