范式的概念:
设计关系数据库时,我们通过遵循不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求就是范式。
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
第一范式
第一范式是指在同一表中没有重复项出现,如果有则应将重复项去掉,这个去掉重复项的过程称为规范化处理。
第一范式关系型数据库最基本的要求,每个关系型数据库一定是符合第一范式的。
不符合:
学生名 | 选课 |
---|---|
张三 | 数学,语文 |
李四 | 物理,数学 |
符合:
学生名 | 选课 |
---|---|
张三 | 语文 |
张三 | 数学 |
李四 | 物理 |
李四 | 数学 |
概念
候选码=关键字:若关系中的某一属性组的值能唯一的标识一个元组,而其任何真子集都不能再标识,则称该属性组为候选码。
主码=主键=主关键字:一个关系中有多个候选码,选择其中一个为主码。
主属性:包含在任一候选关键字中的属性称主属性。
非主属性:不包含在主码中的属性称为非主属性。
第二范式
第二范式 是指每个表必须有且仅有一个数据元素为主关键字 ,其他数据元素与主关键字一一对应。通常称这种关系为函数依赖(Functional dependence)关系。
它的规则是要求数据表里的所有非主属性都要和该数据表的主键有完全依赖关系;如果有哪些非主属性只和主键的一部份有关的话,它就不符合第二范式。
由此得出结论:如果一个表满足第一范式,并且一个数据表的主键只有单一一个字段的话,它就一定符合第二范式。
学号 | 姓名 | 年龄 | 课程名 | 成绩 | 学分 |
---|---|---|---|---|---|
111 | 张三 | 13 | 语文 | 90 | 3 |
111 | 张三 | 13 | 数学 | 95 | 4 |
112 | 王五 | 14 | 语文 | 90 | 3 |
(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)
存在非主属性对主码:(课程名称) → (学分) ,(学号) → (姓名, 年龄) 所以存在部分函数依赖,不符合第二范式。
存在的问题:
数据冗余:
姓名,年龄存了好多遍。
插入异常 :
假设要开设一名新的课程,但是此时没有人选修,由于没有“学号”所以会插入不到数据库。
更新异常:
如果修改了某门课程得学分,则数据库中该课程对应的所有行都必须要修改,否则会出现学分不同。
删除异常
当学生选修玩课程之后,相应的课程就要从数据库删除,会导致学号一块删除。
拆分表以满足第二范式
(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)
(课程名称) → (学分) ,(学号) → (姓名, 年龄)
学生:student(学号,姓名,年龄)
课程:course(课程名称,学分)
选课关系:selectCourse(学号,课程名称,成绩)
student
学号 | 姓名 | 年龄 |
---|---|---|
111 | 张三 | 13 |
112 | 王五 | 14 |
course
课程名 | 学分 |
---|---|
语文 | 3 |
数学 | 4 |
selectCourse
学号 | 课程名 | 成绩 |
---|---|---|
111 | 语文 | 90 |
111 | 数学 | 95 |
112 | 语文 | 90 |
第三范式
在2NF的基础上,任何非主属性不依赖于其他非主属性。(在2NF上消除传递依赖)
如果存在"A → B → C"的决定关系,则C传递函数依赖于A。
关键字段z—>非关键字段x—>非关键字段y
有如下关系:
(学号)—>(姓名,年龄,所在学院,学院地点)
学号 | 姓名 | 年龄 | 所在学院 | 学院地点 |
---|---|---|---|---|
111 | 张三 | 13 | 计算机 | 9号教学楼 |
112 | 王五 | 14 | 化工 | 12号教学楼 |
因为存在关系:
(学号)—>(所在学院)
(学号)—> (学院地点)
(所在学院)—>(学院地点)
非主属性学院地点,对非主属性学号存在传递函数依赖。
解决方案:
(学号,姓名,年龄,学院)
(学院,学院地点)
学号 | 姓名 | 年龄 | 学院 |
---|---|---|---|
111 | 张三 | 13 | 计算机 |
112 | 王五 | 14 | 化工 |
学院 | 学院地点 |
---|---|
计算机 | 9号教学楼 |
化工 | 12号教学楼 |
第三范式异常
仓库id | 管理员id | 存储物品id | 数量 |
---|---|---|---|
1 | 101 | 10001 | 35 |
2 | 102 | 20001 | 30 |
3 | 103 | 30002 | 20 |
3 | 103 | 30003 | 30 |
(仓库id,存储物品id,管理员id,数量),且有一个管理员只在一个仓库工作
,一个仓库可以存储多种物品。
有如下关系:
(仓库id,存储物品id)—>(管理员id,数量)
(管理员id,存储物品id)—>(仓库id,数量)
唯一的非主属性“数量”,
它满足第三范式。
1.删除异常
清仓处理后,所有存储物品id都被删除,管理员和仓库都随即删除。
2.插入异常
当仓库没有存储任何物品时,无法给仓库分配管理员。
3.更新异常
如果仓库换了管理员,表中所有管理员id都需要修改。
原因:
存在主键之间的互相依赖的情况(仓库id—>管理员id)(管理员id—>仓库id)
拆分:
表1(仓库id—>管理员id)
表2(仓库id—>存储物品id—>数量)
BCNF定义
编辑
关系模式R<U,F>∈1NF。若函数依赖集合F中的所有函数依赖X→Y(Y不包含于X)的左部都包含R的任一候选键,则R∈BCNF。换言之,BCNF中的所有依赖的左部都必须包含候选键。
具有函数依赖集的关系模式R属于BCNF的条件是,对所有F的闭包中形如
X->Y,则下面的两个条件至少有一个成立:
-
X->Y是平凡的依赖。
-
X是R的一个超键。
满足BCNF条件
编辑
1 所有非主属性对每一个候选键都是完全函数依赖
2 所有的主属性对每一个不包含它的候选键,也是完全函数依赖;
3 没有任何属性完全函数依赖于非候选键的任何一组属性。
BCNF举例
由于R∈BCNF,按定义排除了任何属性对键的传递依赖与部分依赖,所以R∈3NF。但是若R∈3NF,则R未必属于BCNF。
例如:关系模式 STJ(S,T,J)中,S表示学生,T表示教师,J表示课程。每一个教师只教一门课。每门课有 若干个教师,某一学生选定某门课,就对应一个固定的教师。由语义可得到如下函数依赖
(S,J)->T;(S,T)->J;T->J。
(S,J),(S,T)都是候选键
STJ是3NF,因为没有任何非主属性对键传递依赖或部分依赖。但STJ不是BCNF关系,因为T是决定因素而T不是超键。
分解为BCNF方法
需要消除不包含关系。
1.假设R(U)不是BCNF, X是R的属性子集,A是R的单个属性,X->A是导致违反BCNF的函数依赖,则将R分解为R-A以及XA。
2.若R-A以及XA仍然不是BCNF,则在R-A以及XA递归地执行上述分解。
例SCT:(S#,CNAME,TNAME),FD:TNAME→CNAME。
可分解为SC(S#,TNAME)和CT(CNAME,TNAME),它们都是BCNF。
第四范式
设关系R(X,Y,Z),其中X,Y,Z是成对的、不相交属性的集合。若存在非平凡多值依赖,则意味着对R中的每个属性
存在有函数依赖
(X必包含键)。那么
。
换句话说,当关系R的属性集合X是非平凡多值依赖的域,它就包含关系R的键。则
。这个定义和BCNF定义唯一的不同点是后者研究非平凡
多值依赖
的域。由于函数依赖是多值依赖的特定情况,因此,这直观地说明了4NF比BCNF更强的原因。
显然,若关系属于4NF,则它必属于BCNF;而属于BCNF的关系不一定属于4NF。
第五范式
05255)]
存在有函数依赖
[外链图片转存中…(img-jHKnB5gL-1569064605257)] (X必包含键)。那么
[外链图片转存中…(img-QOQP6KDN-1569064605258)]
。
换句话说,当关系R的属性集合X是非平凡多值依赖的域,它就包含关系R的键。则
[外链图片转存中…(img-0dXgGa1J-1569064605258)]
。这个定义和BCNF定义唯一的不同点是后者研究非平凡
多值依赖
的域。由于函数依赖是多值依赖的特定情况,因此,这直观地说明了4NF比BCNF更强的原因。
显然,若关系属于4NF,则它必属于BCNF;而属于BCNF的关系不一定属于4NF。