范式
数据库设计的⼀套要求。
要求要说满⾜,所以有“满⾜第⼏范式”。
⽬的
消除数据冗余。即,做到同样的数据不存第⼆遍。
惯例
现在数据库设计最多满⾜3NF,普遍认为范式过⾼,虽然具有对数据关系更好的约束性,但也导致数据关系表增加⽽令数据库 I/O 更易
繁忙,原来交由数据库处理的关系约束现更多在数据库使⽤程序中完成。
( 参考:https://zh.wikipedia.org/wiki/数据库规范化 )
“三范式”虽然有⽤,但仍然要具体问题、具体分析,该打破打破。
套路
问题⼀:如何解决 “两条记录完全重复”?
学号 | 姓名 | 年龄 |
---|---|---|
20125112 | 张三 | 22 |
20125113 | 李四 | 21 |
20125112 | 张三 | 22 |
法1:加主键,要求主键不能重复。
「第⼀范式要求:1.要有主键」
法2:设计⼀张只有⼀个字段的表。(字段名info,字符串型)
info |
---|
20125112_张三_22 |
这样就不会有重复数据了,但是傻⼦才会这样设计。
这样不便查询年龄等原⼦信息,需全部拿出正则切割。
傻⼦都能设计出满⾜1NF的表格。
「第⼀范式要求:2.列不可分」
例外
“产品批号”往往以位段藏蕴多层信息,却不必分割保存,只作为⼀个⾃然单位。-
注意
列不可分,却也不能重复。- 两个字段都是“年龄”
- “出⽣年⽉”与“年龄”。
灵活
有些故意存在的冗余是为了程序好写。
问题⼆:设计“多对多”关系表时有哪些注意?
学⽣选课表。
学号、学⽣姓名、⼯号、教师姓名。
学⽣姓名、⽼师姓名冗余。若觉还好,那同时再有“教师简介”字段呢?
如何解决冗余?
- 思路
表要有主键,思考主键担当。
学号可以重复,不能担当主键。
学号和教师编号⼀起,担当“组合主键”
于是,该表就不合2NF了。
「第⼆范式要求:当⼀张表有多个字段作为“组合主键”时,不是主键的那些字段,不能够依赖于“组合主键”的一部分(“部分主
键”)。」
⽩话⽂:
某些字段不能依赖于⼀部分主键,⽽要依赖于整个主键的组合。
叫,不能存在“部分依赖”。
(字段不能部分依赖于主键 → 翻译成人话
→ 字段不能依赖于部分主键)
(有组合主键,才谈得上部分依赖)
如,学⽣姓名依赖于学号,学号不是主键,学号是主键的⼀部分。
这叫“部分依赖”,会产⽣数据冗余。
-
对策
拆表。- 学⽣表(id学号,学⽣姓名)
- 教师表(id⼯号,教师姓名)
- 关系表(学号,⼯号)
检索
表连接。
问题三:Student (id学号, 姓名, 年龄, 性别, 系别, 系办地址, 系办电话) 有啥问题?
概念
a→b 意为 a决定b,b依赖a。可知
(学号)→ (姓名,年龄,性别,系别,系办地址,系办电话)
却⼜:
(学号)→ (系别)→(系办地点,系办电话)
于是,该表就不合3NF了。
「第三范式要求:不是主键的这些字段必须“直接依赖”于主键。」
⽩话⽂:
某些字段除了依赖主键,不能还可以依赖于不是主键的字段。
叫,不能存在“传递依赖”。
(主键字段 → ⾮主键字段x → ⾮主键字段y)
(直接依赖于的字段,就是紧贴在前的决定字段)
(直接依赖,对应的是传递依赖)
如,系办地点、系办电话直接依赖于系别,系别直接依赖于学号。这叫,系办地点、系办电话“传递依赖”于学号,会产⽣数据冗余。
对策
拆表。学⽣(id学号,姓名,年龄,性别,系别)
系别(id系别,系办地址,系办电话)
检索
表连接。
以下可略:BCNF范式
「BCNF范式的要求:不存在主键字段决定主键字段的情况。」
- 对策
将主键中能“⼀对⼀”的关系,拆出来另建表存。 - 仓库管理关系表(仓库ID, 存储物品ID, 管理员ID, 数量)
⼀个管理员只在⼀个仓库⼯作。⼀个仓库可以存储多种物品。
- 可知
(仓库ID, 存储物品ID) → (管理员ID, 数量)
(管理员ID, 存储物品ID) → (仓库ID, 数量)
却⼜:
(仓库ID) → (管理员ID)
(管理员ID) → (仓库ID)
参考:数据库范式1NF 2NF 3NF BCNF实例分解
http://blog.csdn.net/fpf_721521/article/details/548927