可惜事已至此,复习不完也要复习完了。。。所以————————————
《数据库系统原理》常用知识#
怎么快速判断一个关系最高到哪个范式#
可以用一个很快的判断流程。考试时不要从定义硬背,按这个顺序走:
先求候选码
再分主属性/非主属性
再看函数依赖左边是不是码
最后看多值依赖text第一步:先找候选码
这是所有范式判断的基础。
做法:
- 出现在右边的属性,通常不必一开始放进码。
- 从来不出现在右边的属性,通常必须在候选码里。
- 用属性闭包
X+看能不能推出全部属性。 - 能推出全部属性,并且去掉任何一个属性后都不能推出全部属性,就是候选码。
例如:
R(A,B,C,D)
F = {A -> B, C -> D}text右边出现过:
B, Dtext没出现在右边:
A, Ctext所以先试:
(AC)+text有:
A -> B
C -> Dtext所以:
(AC)+ = ABCDtext因此候选码是:
ACtext第二步:分主属性和非主属性
主属性:出现在某个候选码中的属性
非主属性:不出现在任何候选码中的属性text刚才例子里候选码是:
ACtext所以:
主属性:A, C
非主属性:B, Dtext这一步很重要,因为 2NF、3NF 都要看非主属性。
第三步:判断 1NF
1NF 最简单:
属性值不可再分,每个单元格只能放一个值。
如果表里有这种东西:
学生 电话
张三 123, 456text一个格子里放多个电话号码,就不满足 1NF。
一般教材题默认已经满足 1NF,除非题目明显给出“多值属性”。
第四步:判断 2NF
2NF 要求:
非主属性不能部分依赖于候选码。
只在候选码是组合码时容易出问题。
判断口诀:
如果候选码是单属性码,一定满足 2NF。
如果候选码是组合码,就看有没有“候选码的一部分 -> 非主属性”。text例如:
R(A,B,C,D)
候选码:AC
F = {A -> B, C -> D}text有:
A -> Btext其中 A 是候选码 AC 的一部分,B 是非主属性。
所以:
B 部分依赖于候选码 ACtext违反 2NF。
因此这个关系最高只能到:
1NFtext第五步:判断 3NF
3NF 要求:
非主属性不能传递依赖于候选码。
常见违反形式:
候选码 -> 非主属性1 -> 非主属性2text也就是:
X 是候选码
X -> A
A -> Btext其中 A、B 都是非主属性。
例如:
R(Sno, Sdept, Mname)
F = {Sno -> Sdept, Sdept -> Mname}text候选码:
Snotext有:
Sno -> Sdept -> Mnametext所以 Mname 传递依赖于 Sno,违反 3NF。
这个关系如果没有部分依赖,那就是:
最高 2NFtext更快的 3NF 判断公式是:
对于每个非平凡函数依赖:
X -> Atext至少满足一个:
X 是超码
A 是主属性text否则就不满足 3NF。
第六步:判断 BCNF
BCNF 比 3NF 更严格。
BCNF 要求:
对每个非平凡函数依赖
X -> Y,X 必须是超码。
口诀:
只要有一个非平凡函数依赖的左边不是超码,就不是 BCNF。text例如:
R(A,B,C)
F = {AB -> C, C -> B}text候选码可能是:
AB, ACtext所以主属性:
A, B, Ctext看依赖:
C -> Btext右边 B 是主属性,所以它满足 3NF。
但是 C 不能推出全部属性,不是超码。
所以:
不满足 BCNFtext因此这个关系:
最高 3NFtext这也是 3NF 和 BCNF 的典型区别。
第七步:判断 4NF
4NF 是在 BCNF 基础上进一步看多值依赖。
4NF 要求:
对每个非平凡多值依赖
X ->-> Y,X 必须是超码。
口诀:
函数依赖看 BCNF
多值依赖看 4NFtext如果有:
X ->-> Ytext并且:
Y 不包含于 X
X ∪ Y 不是全部属性
X 不是超码text那么就违反 4NF。
典型例子:
Teaching(C, T, B)text含义:
C = 课程
T = 教师
B = 教材text一门课程有多个教师,也有多本教材,教师和教材独立。
存在:
C ->-> T
C ->-> Btext但是 C 不是候选码,所以违反 4NF。
因此要拆成:
CT
CBtext你可以直接背这个快速判断表:
1NF:
属性不可再分。
2NF:
在 1NF 基础上,非主属性不能部分依赖于候选码。
重点看:组合候选码的一部分 -> 非主属性。
3NF:
在 2NF 基础上,非主属性不能传递依赖于候选码。
重点看:候选码 -> 非主属性 -> 非主属性。
BCNF:
每个非平凡函数依赖 X -> Y,X 都必须是超码。
重点看:有没有左边不是超码的函数依赖。
4NF:
每个非平凡多值依赖 X ->-> Y,X 都必须是超码。
重点看:有没有非候选码决定多个独立取值集合。text考试最快流程:
1. 求候选码
2. 标主属性、非主属性
3. 看有没有部分依赖
有:最高 1NF
4. 看有没有传递依赖
有:最高 2NF
5. 看每个函数依赖左边是不是超码
不是:最高 3NF
6. 看有没有非平凡多值依赖且左边不是超码
有:最高 BCNF
7. 都没有:4NFtext注意最后一句:
“最高到哪个范式”就是从低往高查,第一次违反的前一级,就是最高范式。
达到BCNF的无损连接分解算法#
这页讲的是:如何把一个关系模式分解到 BCNF,并且保证无损连接。
核心思想很简单:
只要某个关系模式不满足 BCNF,就找出一个违反 BCNF 的函数依赖,用它把表拆成两张表。反复拆,直到所有表都满足 BCNF。
设原关系模式是:
R<U, F>text其中:
U = 属性全集
F = 函数依赖集text算法输出:
ρ = {R1, R2, ..., Rk}text要求:
- 每个
Ri都是 BCNF - 整个分解是无损连接分解
BCNF 的判断标准是:
对于每个非平凡函数依赖 X -> A,
X 必须是超码。text如果存在:
X -> Atext并且:
X 不是超码text那么这个关系就不是 BCNF。
这页算法的重点是第 3 步:
如果某个关系 Ri<Ui, Fi> 不是 BCNF,那么一定存在某个违反 BCNF 的函数依赖:
X -> Atext满足:
X -> A 是非平凡函数依赖
X 不是 Ri 的码text然后把 Ri 分解成两个关系:
S1 = X ∪ {A}
S2 = Ui - {A}text课件写成:
US1 = XA
US2 = Ui - {A}text也就是:
Ri(Ui) 分解为 S1(X,A) 和 S2(Ui - A)text注意:X 还保留在 S2 里,因为 US2 = Ui - {A},只删掉右边那个属性 A,不删 X。
举个例子:
R(A, B, C)
F = {A -> B}text先判断是不是 BCNF。
候选码是:
ACtext因为:
A -> B
AC -> ABCtext所以 AC 是码。
但是有依赖:
A -> Btext其中 A 不是超码,因为:
A+ = {A, B}text推不出 C。
所以:
R(A,B,C) 不满足 BCNFtext按照算法,用违反 BCNF 的依赖:
X -> Atext这里为了避免和属性名混淆,可以写成:
X -> Ytext具体是:
A -> Btext则:
S1 = A ∪ B = AB
S2 = U - B = ACtext所以分解为:
R1(A, B)
R2(A, C)text为什么这样分解是无损连接?
因为分解后:
R1(A,B)
R2(A,C)text它们的公共属性是:
Atext而已知:
A -> Btext也就是说:
公共属性 A -> R1 - R2text所以这个二元分解是无损连接的。
通用地看:
S1 = XA
S2 = Ui - {A}text两个表的交集是:
S1 ∩ S2 = Xtext因为 X 在两边都有。
而:
X -> Atext所以:
X -> S1 - S2text因此这一步分解一定是无损连接的。
这就是算法为什么能保证“达到 BCNF 的无损连接分解”。
但是要注意一个很重要的问题:
这个算法保证无损连接,但不一定保持函数依赖。
也就是说,拆完以后:
自然连接不会出错text但原来的某些函数依赖可能无法只在单张小表里检查,需要连接后才能检查。
所以 BCNF 分解的特点是:
优点:一定无损连接,并且每个子关系达到 BCNF
缺点:不一定保持函数依赖text再用一个经典例子说明。
R(A, B, C)
F = {AB -> C, C -> B}text先求候选码:
AB 是候选码
AC 也是候选码text因为:
AB -> C,所以 AB+ = ABC
C -> B,所以 AC+ = ABCtext看依赖:
AB -> CtextAB 是候选码,没问题。
再看:
C -> BtextC 不是超码,因为:
C+ = {C, B}text推不出 A。
所以违反 BCNF。
按照算法,用:
C -> Btext分解:
S1 = C B
S2 = U - B = A Ctext得到:
R1(C, B)
R2(A, C)text检查:
R1(C,B)text有:
C -> BtextC 是 R1 的候选码,所以是 BCNF。
R2(A,C)text没有非平凡函数依赖,通常也是 BCNF。
所以最终分解为:
{ R1(C,B), R2(A,C) }text是 BCNF 无损连接分解。
这页你可以记成一句考试口诀:
发现 X -> A 违反 BCNF,
就拆成 XA 和 U - A。
反复拆,直到每个表都是 BCNF。text其中“违反 BCNF”的意思是:
X -> A 非平凡,且 X 不是超码。text达到3NF且保持函数依赖的分解算法#
这页是讲:
把关系模式分解到 3NF,并且保持函数依赖。
它和前面的 BCNF 分解算法不同:
BCNF 分解:保证无损连接,但不一定保持函数依赖
3NF 分解:保证保持函数依赖,通常也可通过补候选码保证无损连接text先看输入:
R<U, F>text其中:
U = 全部属性集
F = 函数依赖集text目标是分解成:
ρ = {R1, R2, ..., Rk}text并且每个 Ri 都满足 3NF。
第 1 步:求最小函数依赖集 F’
也叫最小覆盖、最小依赖集。
它要满足:
- 每个依赖右边只有一个属性:
X -> Atext- 左边没有多余属性。
- 整个依赖集中没有多余依赖。
比如:
A -> BCtext要先拆成:
A -> B
A -> Ctext如果有:
AB -> Ctext但其实:
A -> Ctext也能推出,那么 B 就是多余属性,要删掉。
第 2 步:如果 F’ 中有 X -> A,并且 XA = U,就不用分解
这里:
XA = Utext意思是:
X ∪ {A} = 全部属性集 Utext也就是这个函数依赖已经覆盖了整个关系模式。
例如:
R(A,B,C)
F' = {AB -> C}text这里:
AB ∪ C = ABC = Utext所以直接:
ρ = {R}text算法结束。
直观理解:
这个依赖已经说明 AB 能决定整个关系,原关系通常已经足够好,不需要再按这个算法拆。
第 3 步:找出没有出现在 F’ 中的属性,单独构成一个关系模式
课件写:
找出不在 F’ 中出现的属性,将它们构成一个关系模式,并从 U 中去掉它们。
这里“不在 F’ 中出现”指的是:
这个属性既没有出现在任何依赖的左边,也没有出现在任何依赖的右边。
比如:
R(A,B,C,D,E)
F' = {A -> B, C -> D}text这里 E 没有出现在任何函数依赖里。
所以把它单独拿出来:
R0(E)text然后剩余属性继续处理:
U = {A,B,C,D}text为什么要这样做?
因为 E 和任何依赖都没关系,放在哪个依赖生成的小表里都不自然,所以先单独保留,避免属性丢失。
第 4 步:对 F’ 中每个 X -> A,构造一个关系模式 XA
也就是:
X -> Atext生成:
R(X,A)text例如:
F' = {A -> B, C -> D}text就生成:
R1(A,B)
R2(C,D)text如果多个依赖左边相同,可以合并。
比如:
A -> B
A -> C
A -> Dtext不用生成三个表:
AB
AC
ADtext可以合并成一个:
A B C Dtext也就是:
R(A,B,C,D)text因为它们都是由 A 决定的属性。
第 5 步:删除被包含的关系模式
如果出现:
Ui ⊆ Ujtext就删掉较小的 Ui。
例如分解结果里有:
R1(A,B)
R2(A,B,C)text因为:
{A,B} ⊆ {A,B,C}text所以 R1(A,B) 可以删掉,只保留:
R2(A,B,C)text原因是 R1 的属性已经完全包含在 R2 里,单独保留会冗余。
来个完整例子:
R(A,B,C,D)
F = {A -> B, C -> D}text最小依赖集就是:
F' = {A -> B, C -> D}text按第 4 步:
A -> B 生成 R1(A,B)
C -> D 生成 R2(C,D)text所以得到:
ρ = {R1(A,B), R2(C,D)}text但是注意:这里属性覆盖不完整吗?
R1 ∪ R2 = {A,B,C,D}text完整,所以没丢属性。
每个关系都满足 3NF:
R1(A,B): A -> B,A 是码
R2(C,D): C -> D,C 是码text所以结果是 3NF 分解。
不过这里要特别注意一个考试点:
这个算法主要保证“保持函数依赖”。
因为每个依赖 X -> A 都被放进了一个关系模式 XA 里,所以原来的函数依赖可以在分解后的表中直接检查。
比如:
A -> Btext在 R1(A,B) 里检查。
C -> Dtext在 R2(C,D) 里检查。
不需要把表连接回去再检查。
但是如果题目要求:
既保持函数依赖,又无损连接text通常还要补一步:
如果分解结果中没有任何一个关系模式包含原关系的候选码,就再加入一个候选码关系。
比如:
R(A,B,C,D)
F = {A -> B, C -> D}text候选码是:
ACtext刚才得到:
R1(A,B)
R2(C,D)text没有任何一个表包含候选码 AC。
所以为了保证无损连接,通常还要加入:
R3(A,C)text最终:
ρ = {R1(A,B), R2(C,D), R3(A,C)}text这样才是常见教材里的:
无损连接且保持函数依赖的 3NF 分解text所以这页你可以这样记:
3NF 保依赖分解算法:
1. 求最小依赖集 F'
2. 每个 X -> A 生成一个表 XA
3. 相同左部的依赖合并
4. 删除被其他表包含的小表
5. 若要求无损连接,检查是否含候选码;没有就补一个候选码表text一句话版:
BCNF 分解是“发现违规就拆”;3NF 分解是“按最小依赖集造表”。
达到3NF既保持函数依赖又无损连接的分解#
这页是在补全前一页的问题:
前一个算法 6.4 可以得到 保持函数依赖的 3NF 分解,但不一定保证 无损连接。 算法 6.5 就是在它的基础上,补一个“候选码关系”,从而保证无损连接。
先看它的输入条件:
设 ρ = {R1<U1,F1>, ..., Rk<Uk,Fk>}text这是 R<U,F> 的一个 保持函数依赖的 3NF 分解。
也就是说,ρ 已经满足两个性质:
1. 每个 Ri 都是 3NF
2. 保持函数依赖text但是它可能还没有保证:
无损连接text所以算法 6.5 的目标是:
3NF + 保持函数依赖 + 无损连接text关键步骤是:
设 X 为 R<U,F> 的码text也就是先找原关系 R 的一个候选码 X。
然后检查:
是否存在某个 Ui,使得 X ⊆ Uitext意思是:
分解后的某张表里,是否已经包含了原关系的候选码。
如果有,那么:
ρ 即为所求text也就是不用再补表。
如果没有,就新增一张表:
R*(X)text最终:
τ = ρ ∪ {R*<X, FX>}text其中 FX 是 F 在 X 上的投影。
简单说就是:
如果现有分解里没有任何一个关系包含候选码,就额外加一张“候选码表”。
举个例子,还是这个:
R(A,B,C,D)
F = {A -> B, C -> D}text先求候选码。
因为:
A -> B
C -> Dtext所以:
AC -> ABCDtext因此候选码是:
ACtext用算法 6.4 按最小依赖集造表:
A -> B 得 R1(A,B)
C -> D 得 R2(C,D)text所以得到:
ρ = {R1(A,B), R2(C,D)}text它保持函数依赖,因为:
A -> B 在 R1 中
C -> D 在 R2 中text每张表也都是 3NF。
但是它无损吗?不一定。
检查有没有某个 Ui 包含候选码 AC:
U1 = {A,B}
U2 = {C,D}
X = {A,C}text显然:
AC ⊄ AB
AC ⊄ CDtext没有任何一张表包含候选码 AC。
所以要补一张:
R3(A,C)text最终分解为:
τ = {R1(A,B), R2(C,D), R3(A,C)}text这就同时满足:
1. 3NF
2. 保持函数依赖
3. 无损连接text为什么补候选码表就能保证无损连接?
直观理解:
候选码能唯一标识原关系中的一行。 如果分解结果中保留了一张候选码表,就相当于保留了原表元组之间的“骨架”,自然连接时不容易乱配出假元组。
比如刚才如果只有:
R1(A,B)
R2(C,D)text它们没有公共属性,连接回来会变成笛卡尔积,很容易多出假元组。
加上:
R3(A,C)text之后:
R1(A,B) 通过 A 和 R3(A,C) 连接
R2(C,D) 通过 C 和 R3(A,C) 连接textR3(A,C) 把 A 和 C 的正确搭配保存下来了,所以不会乱配。
最后这句:
如发现某个 Ui ⊆ X,则应将 Ui 去掉text意思是:
如果原来某张表的属性集完全包含在候选码表
X里面,那它就没必要单独保留了。
比如候选码是:
X = {A,C}text如果原来分解里已经有:
R1(A)text那:
{A} ⊆ {A,C}text加入 R*(A,C) 后,R1(A) 就被包含了,可以删掉。
这是为了去掉冗余关系模式。
所以算法 6.5 可以这样记:
先用算法 6.4 得到保持函数依赖的 3NF 分解;
再看有没有表包含原关系候选码;
有:结束;
没有:补一张候选码表;
如果有小表被候选码表包含,就删掉小表。text一句话总结:
算法 6.5 = 算法 6.4 的结果 + 必要时补一个候选码关系,从而保证无损连接。
关于无损分解的总结#
可以把这部分压缩成三个考点:
1. 判断是否保持函数依赖
2. 判断是否无损连接
3. 构造“保持FD + 无损连接 + 3NF”的分解text这也正好对应 PPT 6.5 的复习点:保持函数依赖如何判定、无损连接如何判定,以及算法 6.5:无损连接 + 保持函数依赖的 3NF 分解。
考点一:保持函数依赖#
它问的是:
分解以后,原来的函数依赖还能不能在各个子关系中检查?text设原关系:
R(U, F)text分解为:
ρ = {R1(U1), R2(U2), ..., Rn(Un)}text每个子关系上能保留一部分函数依赖:
F1 = F 在 U1 上的投影
F2 = F 在 U2 上的投影
...
Fn = F 在 Un 上的投影text令:
G = F1 ∪ F2 ∪ ... ∪ Fntext如果:
F+ = G+text就叫保持函数依赖。PPT 的定义也是:如果 F 与 F1∪F2∪...∪Fn 等价,则该分解保持函数依赖。
考试中通常这样写:
求各子关系上的投影 F1, F2, ...
令 G = F1 ∪ F2 ∪ ...
检查 F 中每条函数依赖是否能由 G 推出。
若都能推出,则保持FD;
若有一条推不出,则不保持FD。text例如:
R(A,B,C)
F = {A -> B, B -> C}
ρ = {AB, AC}text分解后:
AB 上有 A -> B
AC 上有 A -> Ctext所以:
G = {A -> B, A -> C}text但是原来的:
B -> Ctext不能由 G 推出。
所以:
ρ = {AB, AC} 不保持函数依赖text记住一句话:
保持FD看的是:约束还能不能在分解后的表中局部检查。text考点二:无损连接#
它问的是:
分解后的表自然连接回来,会不会多出假元组?text如果:
R = R1 ⋈ R2 ⋈ ... ⋈ Rntext就叫无损连接。PPT 中也说,若 R 与 R1、R2、...、Rn 自然连接的结果相等,则该分解具有无损连接性。
最常考的是二分解:
R -> R1, R2text判断规则:
如果 (R1 ∩ R2) -> (R1 - R2)
或者 (R1 ∩ R2) -> (R2 - R1)
属于 F+
则无损连接。text也可以记成:
交集 -> 某一边的差集text只要推出其中一个差集就够,不需要两个都推出。
例如:
R(A,B,C)
F = {A -> B, C -> B}
ρ = {AC, BC}text计算:
AC ∩ BC = C
AC - BC = A
BC - AC = Btext因为:
C -> Btext所以:
C -> BC - ACtext因此:
ρ = {AC, BC} 是无损连接textPPT 例 6.20 正是这样判断的:AC∩BC=C,BC-AC=B,由于 C→B∈F+,所以该分解具有无损连接性。
但是注意:
无损连接 ≠ 保持函数依赖text无损连接看的是:
连接回来会不会出错text保持 FD 看的是:
依赖约束有没有丢text这两个是不同性质。
考点三:构造“保持FD + 无损连接 + 3NF”的分解#
这是让你自己分解。
目标是得到:
ρ = {R1, R2, ..., Rn}text满足:
1. 每个 Ri 达到 3NF
2. 保持函数依赖
3. 无损连接textPPT 算法 6.5 说:先得到一个保持函数依赖的 3NF 分解;若已有某个子模式包含原关系的码,则该分解就是所求;否则再加入一个由码构成的关系。
考试步骤可以写成:
第一步:求最小函数依赖集#
把 F 化成最小依赖集:
右边单属性;
左边无多余属性;
依赖本身无多余。text例如:
A -> BCtext先拆成:
A -> B
A -> Ctext第二步:按每条 FD 建关系#
对每条:
X -> Atext建一个关系:
XAtext如果多条 FD 左部相同,可以合并。
例如:
A -> B
A -> Ctext可以合并成:
ABCtext而不是非要写成:
AB, ACtext第三步:检查是否包含候选码#
看当前分解中有没有某个子关系包含原关系 R 的一个候选码。
如果有,不用加。
如果没有,额外加入一个候选码关系。
注意:
只需要加入一个候选码,不需要加入所有候选码。text例如候选码有:
AC, BCtext只需要加:
ACtext或者只加:
BCtext任选一个即可。
第四步:删掉被包含的子关系#
如果有:
AB ⊆ ABCtext那么 AB 可以删掉,保留 ABC。
最后压缩成答题口诀#
保持FD:看 F 和各子关系投影并集是否等价。
无损连接:二分解看 交集 -> 某个差集。
3NF分解:最小依赖集建表;若无候选码表,加一个候选码;再删包含项。text再短一点就是:
保持FD管“依赖有没有丢”;
无损连接管“连接会不会多假元组”;
3NF分解管“怎么构造一个既保持FD又无损的分解”。text需要背诵的一些东西#
数据库系统的特点?#
- 数据结构化
数据不再只服务某一个程序,而是面向整个组织;不仅记录内部有结构,数据之间也有联系。
-
数据共享性高、冗余度低、易扩充
-
数据独立性高
-
数据由DBMS统一管理和控制
模型#
概念模型#
数据模型#
层次模型#
适合表示一对多关系
不适合多对多关系
网状模型#
关系模型#
三级模式#
概念模式 / 模式
面向数据库设计人员,描述数据整体逻辑结构
外模式
面向应用程序,靠近用户,描述视图。
不同用户的需求创建不同视图
内模式
面向物理层,描述数据采用什么样的数据结构存储和获取
二级映像#
外模式 / 概念模式映像
保持逻辑独立性:修改概念模式基本表时,不影响外模式
- 每一个外模式都对应一个映像
- 映像定义包含在外模式描述中
概念模式 / 内模式映像
保持物理独立性:修改了内模式,不影响上层的概念模式和外模式
- 唯一
- 包含在模式描述中
三个完整性#
实体完整性#
所有主属性都不能为控制
参照完整性#
外码必须出现在引用中,或者为空值
用户定义完整性#
下次一定好好复习(