-
第六章-关系数据理论
本章的目的:如何构造一个好的数据库模式
6.1 问题的提出:
-
关系模式的表示:
- 关系模式由五部分组成,是一个五元组:R(U,D,DOM,F)
- R表示关系模式名
- U表示一组属性
- D表示U的取值范围,如Son的取值范围是0-100
- DOM表示属性的域映射,如age到整数100,中的映射
- F为属性组U的组数据依赖,如函数依赖,多值依赖等等
-
细节:
- 由于D、DOM与模式设计关系不大,因此在本章把关系模式看作一个三元组:R<U,F>
-
当且仅当 U 上的一个关系 r 满足 F 时, r 称为关系模式 R 的一个关系
- 理解:U是一组属性(如:学生表),如果有一个表里的数据满足U这一组属性(如:学生表),那么该表就是模式里的一个关系
-
作为二维表,关系要符合一个最基本的条件:每个分量必须是不可分的数据项。满足了这个条件的关系模式就属于第一范式(1NF)
- 理解:
-
数据依赖:
-
一个关系内部属性与属性之间的一种约束关系,通过属性间值的相等与否体现出来的数据间相关联系
-
-
数据依赖的主要类型:
-
函数依赖(简记:FD)
- 理解:如:知道学生学号,推出学生姓名,知道学生选课号,推出课程名称
-
多值依赖(简记:MVD)
- 理解:如:和函数一样,但它可以通过一个值推出多个数据
-
函数依赖(简记:FD)
-
函数依赖在现实生活中的体现:
- 例1:描述一个学生关系,可以有学号、姓名、系名等属性
- 一个学号只对应一个学生,一个学生只在一个系中学习,“学号”值确定后,学生的姓名及所在系的值就被唯一确定
- Sname=f(Sno),Sdept=f(Sno) 就即Sno函数决定Sname,Sno函数决定Sdept,记作Sno -> Sname,Sno->Sdpt
- 例2:建立一个描述学校教务的数据库,涉及的对象包括:学生的学号(Sno)、所在系(Sdept)、系主任姓名(Mname)、课程号(Cno)、成绩(Grade)
- 假设学校教务的数据库模式用一个单一的关系模式 Student 来表示,则该关系模式的属性集合为:U = {Sno,Sdept,Mname,Cno,Crade}
-
现实世界的已知事实(语义):
-
① 一个系有若干学生,但一个学生只属于一个系
② 一个系只有一名(正职)负责人
③ 一个学生可以选修多门课程,每门课程有若干学生选修
④ 每个学生学习每一门课程有一个成绩
-
-
由此可得到属性组 U 上的一组函数依赖 F :F = {Sno -> Sdept, Sdept -> Mname, (Sno,Cno) -> Grade}
-
-
函数依赖存在的问题:
-
数据冗余:上述例子中,如果一个学生选择了10本课程,那么系主任的名字就重复10次,就产生了数据冗余
-
更新异常:数据冗余,更新数据时,维护数据完整性代价大。如,系更换系主任后,必须修改与该系学生有关的每一个元组
-
插入异常:如果一个系刚成立,尚无学生,则无法把这个系及其系主任的信息存入数据库,因:学号是主码,课程号是主码,为空那么主任的信息就不能插入
-
删除异常:如果某个系的学生全部毕业了,则在删除该系学生信息的同时,这个系及其系主任的信息也丢掉了,因主码不能为空,为空了信息怎么还存在
-
-
说明:
-
上述的Student关系模式不是一个好的模式,一个“好”的模式应当不会发生插入异常、删除异常和更新异常,数据冗余应尽可能少
-
存在以上问题的原因是这个模式中的函数依赖存在某些不好的性质
-
-
解决方法:用规范化理论改造关系模式来消除其中不合适的函数依赖
-
-
函数依赖的解决方式:
-
用规范化理论改造关系模式来消除其中不合适的函数依赖,就是尽可能的去减少一个表中的多个函数依赖
-
S(Sno,Sdept,Sno -> Sdept)
-
SC(Sno,Cno,Grade,(Sno,Cno) -> Grade)
-
DEPT(Sdept,Mname,Sdept -> Mname)
-
这三个模式都不会发生插入异常、删除异常的问题,数据的冗余也得到了控制
-
6.2 规范化:
- 什么是规范化?如何把不好的数据库(各种函数依赖,数据冗余,更新异常,插入异常删除异常)的数据规范化
6.2.1 函数依赖:
- 什么是函数依赖?如:学号确定姓名,姓名确定学号,但不能一个学号确定多个姓名,一个姓名确定多个学号
- 例:如果Sname是不能重名的
- 有关函数的一些术语和记号:
- 细节1:对于任一关系模式,平凡函数依赖都是必然成立的,它不反映新的语义。若不特别声明,总是讨论非平凡函数依赖
- 细节2:x和y可以是一个,或者是一组
-
X -> Y,但 Y⊈X,则称 X→Y 是非平凡的函数依赖
- 理解:如(Sno,Sname) -> Grade, 那么Grade可以推出Sno或Sname吗?不能这就是非平凡的函数依赖
-
X -> Y,但 Y⊆X,则称 X→Y 是平凡的函数依赖
- 理解:如(Sno,Sname) -> Sno,那么Sno 推出里面其中一个(Sno,Sname)就是平凡的函数依赖
-
若 X→Y,则 X 称为这个函数依赖的决定属性组,也称为决定因素
- 如:通过系名得到系主任的名字,那么系名就是决定因素
- 若 X→Y,Y→X,则记作 X←→Y
- 若 Y 不函数依赖于X,则记作 X Y
-
完全函数依赖:记作: XY
- 什么是完全函数依赖?如:(Sno,Sname) -> Grade,但是Grade推不出来Sno,Sname
- 课本原文:在 R(U) 中,如果 X→Y,并且对于 X 的任何一个真子集 X′ , 都有 X′↛Y, 则称 Y 对 X 完全函数依赖记作 XY
-
部分函数依赖:记住:XY
- 什么是部分函数依赖?如:(Sno,Sname) -> sno或Sname,Sno可以推出(Sno,Sname)里的Sno
- 课本原文:若 X→Y,但 Y 不完全函数依赖于 X,则称 Y 对 X 部分函数依赖记作 部分函数依赖:记住XY
- 例子:
-
Z
-
什么是传递函数依赖:如:(Sno) -> Sdept,Sdept->Mname,就是一个依赖于一个,学号知道系,系不能知道确定学号,系得到系主任
-
Z
-
细节:X和Y不能相互依赖X<->Y,否则就是Z直接依赖于X,就不是传递依赖了
-
6.2.2 码:
- 细节:码也称“键"或"键码"就是叫法不同性质一样
-
候选码:
- 什么是候选码?给定一个值可以确定一条记录,如学生表中的Sno或Sname(学生姓名不能重名),那么Sno和Sname就都是候选码
- 课本原文:设 K 为 R 中的属性或属性组合。若 K→FU ,则 K 称为 R 的候选码(candidate key)
-
主码:
- 什么是主码?主码来自候选码,主码只有一个,但是主码可以是一个属性或多个属性组成,如Sno可以或(Sno,Sname)括号里面的都是主属性
- 细节:候选码中的谁都可以是主码,但主属性只有一个
- 课本原文:若关系模式 R 有多个候选码,则选定其中的一个为主码
-
超码:
- 什么是超码?是在主码间扩招出来的,如:(Sno,Sage)Sno主码加Sage形成一个超码,候选码就是最小的超码
- 课本原文:如果 U 部分函数依赖于 K,即 K→PU ,则 K 称为超码(surpkey)。候选码是最小的超码,即 K 的任意一个真子集都不是候选码
-
全码:
- 什么是全码?所有属性组成,才能确定一条记录
-
外码(外部码):
- 什么是外码?不是本表中的属性,参考于其它表中的属性,来确定信息
- 例子:SC(Sno,Cno,Grade)中,Sno不码,Sno是Student(Sno,Sdept,Sage)的码,则Sno是SC的外码
- 课本原文:关系模式 R 中属性或属性组 X 并非 R 的码,但 X 是另一个关系模式的码,则称 X 是 R 的外部码(foreign key),也称外码,主码与外码一起提供了表示关系(表)间的联系的手段
-
主属性和非主属性:
- 主属性和非主属性是针对,候选码和主码来说的
-
主属性:
- 什么是主属性?包含在任何一个候选码中的属性,称为主属性
-
非主属性:
- 什么是非主属性?不包含在任何候选码中的属性
6.2.3 范式:
-
什么是范式?满足一种级别的关系模式的集合
- 理解:关系数据库中的表,必须满足不同的要求,满足的程度不同就是不同的范式
-
各种范式之间的存在联系:
-
5NF ⊂ 4NF ⊂ BCNF ⊂ 3NF ⊂ 2NF ⊂ 1NF
- 理解:2NF保护1NF,3NF包含2NF(2NF是包含1NF的),以此类推
-
5NF ⊂ 4NF ⊂ BCNF ⊂ 3NF ⊂ 2NF ⊂ 1NF
-
规范化:是指一个低一级范式的关系模式,提供模式分解转换为若干个高一级范式的关系模式集合的过程
- 模式分解:可以理解为把一个关系表分解为多个关系表
- 第一范式-1NF:只要基本表中不出现,像合并单元格的就是第一范式,第一范式是基本前题
-
第二范式-2NF:非主属性(非候选码),要完全函数依赖于任何一个候选码
- 理解:一个表中函数依赖关系必须是完全函数依赖,不能是其他依赖
- 例子:S-L-C(Sno, Sdept, Sloc, Cno, Grade),Sloc 为学生的住处,并且每个系的学生住在同一个地方。S-L-C的码为 (Sno,Cno),则函数依赖有:
-
(Sno, Cno) Grade --> 完全函数依赖
Sno → Sdept,
-
(Sno, Cno) Sdept --> 部分函数依赖,不符合第二范式
Sno → Sloc,
-
(Sno, Cno) Sloc -> 部分函数依赖,不符合第二范式
Sdept → Sloc(每个系的学生只住一个地方)
-
函数依赖关系如下:
- 实线是完全函数依赖
- 虚线是部分函数依赖
- 出现例子上不能形成第二范式的原因是,sdept、Sloc它是部分函数依赖
-
解决办法:
- 用投影分解把关系模式S-L-C分解(前面说到的模式分解)成两关系,消除部分函数依赖
-
SC(Sno,Cno,Grade) 和 S-L(Sno,Sdept,Sloc)
- 虽然分成了两个表,都是是有通过Sno进行表的联系
-
一个关系模式不属于第二范式,产生的问题:
- 插入异常、删除异常、修改复杂
- 第三范式-3NF:不能有传递依赖存,第三范式是包含第二范式,第三范式是在第二范式上改进(上述以说)
- 例子:S-L(Sno,Sdept,Sloc)该关系是上述案例模式分解出来的,它存在函数依赖,Sno -> Sdept -> Sloc,把该问题解决就可以升级为第三范式
- 解决办法:S-D(Sno,Sdept)和D-L(Sdept,Sloc),该两个关系中就不存在函数依赖
-
BCNF范式:BCNF范式是第三范式改进版
-
满足如下条件的就是BC范式:
-
1.所有非主属性对每一个候选码都是完全函数依赖
- 理解:不是码的值,必须对候选码完全函数依赖
-
2.所有主属性对每一个不包含它的候选码也是完全函数依赖
- 理解:码可以推出码,如Sno -> Sname(Sname不能重复)
-
3.没有任何属性完全函数依赖于非码的任何一组属性
- 理解:就是非码,不能推出依赖关系
-
1.所有非主属性对每一个候选码都是完全函数依赖
-
满足如下条件的就是BC范式:
-
例子:C(Cno,Cname,Pcno),它只有一个码 Cno,没有任何属性对 Cno 部分依赖或传递依赖, 所以 C ∈ 3NF。同时 C 中 Cno 是唯一的决定因素,所以 C ∈ BCNF
- 理解:Cno -> Cname ;Cno -> Pcno,依赖关系都是候选码符合条件第2点,没有依赖关系符合第3点,第2点也符合
-
例子:S(Sno,Sname,Sdept,Sage),假定 Sname 也具有唯一性,那么 S 就有两个码,这两个码都由单个属性组成,彼此不相交。其他属性不存在对码的传递依赖与部分依赖,所以 S ∈ 3NF。同时 S 中除 Sno,Sname 外没有其他决定因素,所以 S 也属于 BCNF
- 理解:Sno <-> Sname; (Sno,Sname)-> Sdept; (Sno,Sname) -> Sage ;Sno -> Sdept ;Sno-> Sage ;Sname -> Sage 符合条件的3点
-
例子:关系模式 SJP(S,J,P) 中, S 是学生,J 表示课程,P 表示名次。每一个学生选修每门课程的成绩有一定的名次,每门课程中每一名次只有一个学生(即没有并列名次)
- 理解:(S,J)→P ;(J,P) -> S ,(S,J)与(J,P)都可以作为候选码
-
例子:关系模式 STJ(S,T,J) 中,S 表示学生,T 表示教师,J 表示课程。每一教师只教一门课,每门课有若干教师,某一学生选定某门课,就对应一个固定的教师。由语义可得到函数依赖(S,J)→T ,(S,T)→J , T→J 。
- 理解:因为没有任何非主属性对码传递依赖或部分依赖,STJ∈ 3NF,因为 T 是决定因素,而 T 不包含码, 所以 STJ∉ BCNF
6.3 数据依赖的公理系统:
-
闭包:
- 什么是闭包?就是通过候选码去推导出它的函数依赖(个人理解)
- 课本原文:在关系模式 R<U,F> 中为 F 所逻辑蕴涵的函数依赖的全体叫作 F 的闭包(closure),记为 F+
- 闭包记作:
-
例子1:
-
-
例子2:
-
-
例子3:
-
-
例子4:
-
-
例子5:
-
-
求候选码:
- 什么是求候选码?就是通过函数一拉的两边的出现属性,通过属性的闭包来确定候选码
-
怎么求?:如果函数一拉的左边出现,拼接和N合并去求闭包,看是否可以求出完整的闭包(就是整个R),能求出完整的闭包就是候选码
- 如果有LR两边都出现的,就需要拿L去拼接去求闭包,拼接求出来完整闭包,的LR就不能在用来下一次的拼接
- R不要理
- L表示属性只在函数依赖的左边出现
- R表示属性只在函数依赖的右边出现
- LR表示属性只在函数依赖的左右边出现
- N表示函数依赖的两边都不出现
-
- 例子1:
-
- 例子2:
出处: https://www.cnblogs.com/Mr-shne/p/16850604.html