参考资料:
- https://www.zhihu.com/question/24696366
- https://segmentfault.com/a/1190000013695030
数据库范式
1NF,2NF,3NF和BCNF,实际开发中,常常需要满足1NF或者2NF
第一范式(1NF)
第一范式是属性的原子性,即属性不能再分解。属性1,属性2(属性2.1,属性2.2,属性2.3)…
学号 | 姓名 | 出生年月日 |
---|---|---|
如果以上表格属性出生年月日,分为出生年、出生月、出生日,那就不符合第一范式。
第二范式(2NF)
第二范式是在第一范式基础上,保证记录的唯一性,每一条记录有唯一标识,非主属性不能对码存在部分函数依赖
- 完全函数依赖和部分函数依赖:(完全)学号->院名,(部分)(学号,姓名)->院名
- 码:码==候选码,一个属性组K,除K外的所有属性均完全依赖于K,那么K是码。一个表可以有多个码,通常选用一个码作为主码
- 非主属性:主属性即码的任一属性
学号 | 姓名 | 课程号 | 成绩 |
---|---|---|---|
此表码为(学号,课程号),非主属性:(学号,课程号)-> 成绩,学号 -> 姓名,姓名出现了部分依赖,应当分解为:
学生表:
学号 | 姓名 |
---|---|
成绩表:
学号 | 课程号 | 成绩 |
---|---|---|
第三范式(3NF)
第三范式是在第二范式基础上,消除冗余,消除了非主属性对码的传递函数依赖
学号 | 姓名 | 院名 | 院长名 |
---|---|---|---|
码为学号,学号->院名,院名->院长名,院长名和学号属于传递函数依赖,表中会出现冗余,分解为:
学生表:
学号 | 姓名 | 院名 |
---|---|---|
学院表:
院名 | 院长名 |
---|---|
BCNF
BCNF是在第三范式基础上,消除主属性对码的部分与传递函数依赖
假设:
- 一个仓库只能有一个管理员,管理员也只能在一个仓库工作
- 仓库可以放置多种商品,对应有商品的数量
仓库名 | 管理员 | 物品名 | 数量 |
---|---|---|---|
该表的码为(仓库名,物品名)和(管理员,物品名),主属性为仓库名,管理员,物品名,以(仓库名,物品名)为主码,那么管理员存在部分函数依赖,应当分解为:
仓库表:
仓库名 | 管理员 |
---|---|
库存表:
仓库名 | 物品名 | 数量 |
---|---|---|
总结
- 1NF保证属性的原子性,是数据库必须遵守的
- 2NF保证记录的唯一性,消除部分函数依赖
- 3NF减少冗余,消除传递函数依赖
- 4NF减少插入、删除、更新异常