候选键(候选码):在一个数据库中每行的值都不相同,则可称为候选键.
比如学号, 身份证号
码:含有候选键的组合.(学号,性别) (学号,年龄)
主属性:所有候选码的并集 (学号,身份照号)
非主属性:不在主属性里的属性(年龄,性别)
参考:https://blog.csdn.net/sumaliqinghua/article/details/85872446?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
函数依赖
我觉得对比着理解比较好, 首先就是完全函数依赖和部分函数依赖的对比
1 完全函数依赖
X能推出Y,且X的真子集不能推出Y,那么X->Y就是完全函数依赖
举例说明:
A+B ->C 且A -\→ C, B -\→ C
(Sno,Cno)→Grade 只有学号和课程名都知道, 才能知道某个人的某一门课得了多少分,缺一不可
2 部分函数依赖
如果X能推出Y,且X的真子集也能推出Y,那么X->Y就是部分函数依赖
举例说明:
A+B -> C 且 A -> C 或 B -> C
(Sno,Cno)→Sage 但Sno→Sage,通过学号就可以知道年龄了,课程名只是一个不必要的条件
只有当决定方式组合时,才有讨论部分函数依赖的必要.
3 传递函数依赖
如果X能推出Y,Y能推出Z,X->Z就是传递依赖吗?
不, 还要加一些条件.
X不包含Y,并且Y推不出X才可以!
举例说明:
Sno→Dno Dno→fee 因此Sno->fee
学号确定宿舍、宿舍确定费用,且有学号不包含宿舍,宿舍不确定学号
缺点:
添加异常: 建了宿舍没人住, 无法添加宿舍.
删除异常:学生毕业或者退学,删除学生数据会导致宿舍数据也被删除.
因此要消除传递函数依赖.
范式
1 第一范式
列不能再拆分,举个反例就是,想象一个excel表,如果表头下面还有两个副的表头,那这个就不符合第一范式.
不符合:
分解:把不符合第一范式的列拆分成符合第一范式的列,就是直接把sub的列提取出来变成单独的列:
从第一范式到第二范式就是要消去非主属性对键的部分函数依赖.
2 第二范式:
首先是 1NF,另外包含两部分内容,一是表必须有一个主键;二是第二范式要求每个非主属性完全依赖于主键,而不是仅依赖于其中一部分属性。
我自己觉得一般来说一个表的第一列都是主键(之一).
单个关键字肯定是第二范式.
可以参考:
https://blog.csdn.net/sunzhenhua0608/article/details/16850053
https://baike.baidu.com/item/%E7%AC%AC%E4%BA%8C%E8%8C%83%E5%BC%8F
分解:把完全依赖于主键的列和主键提取出来作为一张表,
再把部分依赖的列和对应的主键中的某一部分提取出来作为另外的表.
从第二范式到第三范式就是要消除非主属性到键的传递函数依赖
3 第三范式:就是指表中的所有数据元素不但要能唯一地被主关键字所标识,而且它们之间还必须相互独立,不存在其他的函数关系。
其实就是看非主属性能不能推出另一个非主属性.
分解:就是把存在传递函数依赖的两个列提取出来,也就是传递函数依赖里的Y和Z. 因为X是主键.
从第三范式到BC范式就是要消除主属性对键的传递函数依赖.
4 BC范式:即存在关键字段决定关键字段的情况
分解:把互相传递的两个主属性提取出来.
再用任意一个和其他的组合.一个表只能有一个候选键.
参考:https://blog.csdn.net/sumaliqinghua/article/details/86246762?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
参考:
https://blog.csdn.net/williamyi96/article/details/66558051