什么是范式
- 概念:设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
- 种类:目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
- 范式之间的关系
- 范式的特点
- 减少数据冗余(这是最主要的好处,其他好处都是由此而附带的)
- 消除异常(插入异常,更新异常,删除异常)
- 让数据组织的更加和谐
- 缺点
范式越高,意味着表越多,多表联合查询的几率就越大,SQL查询的效率就变低
第一范式(1NF)
- 理解:每一列都不可再分割,也就是保持原子特性
- 举例:
不满足第一范式的表
学号 | 姓名 | 家庭住址 |
---|
0001 | 张三 | xx省xx市xx区xx街道xx小区 |
- 数据冗余,如果有多个学生在同一个小区,那么同样的地址要多次存储
- 修改异常,如果有学生更换家庭住址,那么就得对整个家庭住址去修改
- 查询效率太低,如果要查找在xx市的所有学生,那么必须对每个学生的家庭住址整个字段去进行字符匹配
- 修改:表可以拆分为学生表和地址表,表中家庭住址可以拆分为省市区等几个字段
符合第一范式的表
地址ID | 省 | 市 | 区街道 | 小区 |
---|
1 | xx省 | xx市 | xx区 | xx街道 |
第二范式(2NF)
- 理解:在符合第一范式的基础上,消除非主属性对主键的部分依赖,使非主属性完全依赖于主键
- 举例:
不满足第二范式的表
- 关键字为组合关键字(学号, 课程名称),这个数据库表不满足第二范式,因为存在如下决定关系:(课程名称) → (学分) (学号) → (姓名, 年龄),即存在组合关键字中的字段决定非关键字的情况。
- 数据冗余:一门课被多个同学选修,那么课程名称和学分就多次重复存储。
- 插入异常:当有一门新课没人选修时,这门课就因为没有主键而插不进来。
- 删除异常:当一门课之北一个同学选修时,删除这个同学时这门课也会被删除。
- 修改异常:当一门课程的学分需要修改时,就得修改每个选修这门课的同学。
第三范式(3NF)
- 理解:在满足第二范式的基础上,属性不依赖于其它非主属性(消除非主属性对主键的传递依赖)
- 举例:不满足第三范式的表
- 由学生id无法直接推出学院电话,而是由学生id->学院id->学院电话,存在非主属性对主键的传递依赖
- 数据冗余:一个学院有多名学生,那么学院电话就需要存储多次
- 插入异常:当一个学校没有学生时,学院电话就无法存储
- 修改异常:当一个学院电话需要修改时,就需要修改多次
- 删除一场:当一个学院只有一个学生时,学生被删除那么学院电话就被删除
BC范式(BCNF)
巴斯-科德范式(BCNF)是第三范式(3NF)的一个子集,即满足巴斯-科德范式(BCNF)必须满足第三范式(3NF)
-
理解:在满足第三范式基础上,满足一下三个条件
1 所有非主属性对每一个候选键都是完全函数依赖;
2 所有的主属性对每一个不包含它的候选键,也是完全函数依赖;
3 没有任何属性完全函数依赖于非候选键的任何一组属性。
-
举例:假设仓库管理关系表(仓库ID, 存储物品ID, 管理员ID, 数量),且有一个管理员只在一个仓库工作;一个仓库可以存储多种物品。主键(仓库ID,管理员ID, 存储物品ID)
- 我们发现:(仓库ID, 存储物品ID) →(管理员ID, 数量),(管理员ID, 存储物品ID) → (仓库ID, 数量)
所以,(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是仓库管理关系表的候选关键字,表中的唯一非关键字段为数量,它是符合第三范式的。但是,由于存在如下决定关系:
(仓库ID) → (管理员ID),(管理员ID) → (仓库ID)
即存在不满足上述的第二种情况:主属性(管理员)部分依赖于不包含它的候选键(仓库ID, 存储物品ID),所以其不符合BCNF范式。它会出现如下异常情况: - 数据冗余
- 删除异常:当仓库被清空后,所有”存储物品ID”和”数量”信息被删除的同时,”仓库ID”和”管理员ID”信息也被删除了。
- 插入异常:当仓库没有存储任何物品时,无法给仓库分配管理员。
- 更新异常:如果仓库换了管理员,则表中所有行的管理员ID都要修改。
第四范式(4NF)
- 理解:消除表中的多值依赖
- 举例:通俗可能不严谨地讲,就是一个表中只有三个属性X,Y,Z,如果多值依赖X→→Y成立,则对于X、Z中一对值(x,z),确定一组Y值,这组值仅与x有关与z无关。
判断是第几范式
- 范式关系:5NF⊆4NF⊆BCNF⊆3NF⊆2NF⊆1NF。由上面关系可知,假如满足3NF,肯定也满足2NF,以此类推。
- 化简过程:给定一个1NF范式,删去部分函数依赖就是2NF;删去传递函数依赖就是3NF;使每个关系都含有码,就变成了BCNF范式;删除非平凡且非函数依赖的多值依赖就是4NF。