StarkerSong Get Busy Living

数据库设计与范式

2016-09-17

在设计数据库时,我们往往依照数据库的范式降低数据间的冗余度,但是范式就像是把双刃剑,尤其是在大数据时代,有效的增加数据的冗余度,还可以提高数据的访问效率。但是处在初级设计阶段就需要对数据库范式有足够的理解,设计出更加规范的数据库,具体来说常见的范式主要为以下部分:

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: 没有多值依赖

参考资料


Comments