什么是范式
一张数据表的表结构所符合的某种设计标准的级别
主属性
非主属性
1 第1范式 每个属性必定不能再分
错误例子:
编号 品名 进货(数量|单价) 销售(数量|单价) 备注
修改后:
编号 品名 进货数理 进货单价 销售数量 销售单价 备注
2 第2范式 2NF在1NF的基础之上,消除了非主属性对于码的部分函数依赖
错误例子:学号 姓名 系名 系主任 课名 分数
数据冗余过大
新建系如何暂时没有招生,就在数据库创建不了数据进入数据库内-添加异常
学生毕业后删除记录,连系主任都会被删除-删除异常
某学生转系,哪么多条记录中与系主任相关的记录会被修改-修改异常
函数依赖:
系名->系主任
学号->系主任
(学号,课名)->分数
不成立的函数依赖:
学号->课名
学号->分数
课名->系主任
(学号,课名)->姓名 //仔细想课名是决定不了姓名的,一点关系都没有
函数依赖三种类型(完全函数依赖,部分函数依赖,传递函数依赖)
完全函数依赖
在一张表中,若X->Y,X中的任何一个真子集,都无法确定Y,但其全集可以确定,这个就记作XF->Y
eg:学号F-> 姓名
(学号,课名)F->分数 学号或者课名都不能单独确定分数
部分函数依赖
假如Y函数依赖于X,但同时Y并不完全函数依赖于X,记作X P->Y
eg:(学号,课名) P->姓名
也就是说码存在两个主属性以上的时候,才可能会出现非主属性对码的部分函数依赖
传递函数依赖
如果Z函数依赖于Y,且Y函数依赖于X,X不依赖于Y,那么就记作x T-Z
叫Z传递函数依赖于X。
也就是说码和非主属性存在2个以上的时候,才可能会出现非主属性对码的传递函数依赖
码
设K为某表中的一个属性或属性组,若除K之外的所有属性都完全函数依赖于K,称K为码。
主属性
包含在任何一个码中的属性成为主属性
如:学号与课名组成的码,它们两分别为主属性
判断是否符合2NF步骤:
1 找出所有的码
2 根据第1步的码,找出所有的主属性
3 在数据表中,除去所有的主属性,剩下的就都是非主属性
4 查看是否存在非主属性对码的部分函数依赖
eg,使用上面2NF的错误表结构,
诀窍:如果A是码,哪么所有包含了A的属性组都不会是码了,因为作为码的要求里有一个“完全函数依赖”,把属性全部列出来,连线
第一步: 码是(学号,课程)
第二步:主属性:学号与课名
第三步:非主属性:姓名,系名,系主任,分数
第四步:(学号,课名)->姓名 ,学号->姓名, 所以(学号,课名)p->姓名
(学号,课名)->系名,学号->系名,所以(学号,课名)p->系名
(学号,课名)->系主任,学号->系主任,所以(学号,课名)p->系名
解决方案:將大数据表拆分成两个或者更多个更小的数据表,
3 第3范式 3NF在2NF的基础之上,消除了非主属性对于码的传递函数依赖
在2NF的基础上:产生三张新表
表1 选课 (学号 课名 分数)
表2 学生 (学号 姓名 系名)
表3 系 (系名,系主任)
BCNF范式 解偶用的,重点观察插入和删除的时候,属性对应的数据会出现哪些异常
eg:实体(仓库名,管理员,物品名,数量)
主属性:仓库名,管理员,物品名
码:(管理员,物品名),(仓库名,物品名)
主属性不能为空,删除数据,仓库名和管理员会被删除,更改管理员,所以物品的记录会被更新
,所以得出一个结论,即使满足3NF,也可能存在插入,删除,修改异常。
原因是什么?存在主属性对于码的部分函数依赖与传递函数依赖,主属性(仓库名)对于码(管理员,物品名)的部分函数依赖
解决办法:在3NF的基础上消除主属性对于码的部分与传递函数依赖