第 7 章: 关系数据库设计

73
7 7 : : 第第第第第第第 第第第第第第第

Upload: duyen

Post on 21-Jan-2016

107 views

Category:

Documents


0 download

DESCRIPTION

第 7 章: 关系数据库设计. 第 7 章: 关系数据库设计. 第一范式 关系数据库设计中易犯的错误 函数依赖 分解 Boyce - Codd 范式 第三范式 多值依赖与第四范式 数据库设计全过程. 第一范式. 如果域中元素被认为是不可分的, 则域称为是 原子的 非原子域的例子 : 名字集合 , 复合属性 象 CS101 之类的标识号可以分成若干部分 如果关系模式 R 的所有属性的域都是原子的, 则 R 称为属于 第一范式 非原子值存储复杂并易导致数据冗余 E.g. 每个客户的账户集合 , 以及每个账户的拥有者集合 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第 7 章: 关系数据库设计

第第 77 章章 : : 关系数据库设计关系数据库设计

Page 2: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.2Database System Concepts

第第 77 章章 : : 关系数据库设计关系数据库设计

第一范式 关系数据库设计中易犯的错误 函数依赖 分解 Boyce - Codd 范式 第三范式 多值依赖与第四范式 数据库设计全过程

Page 3: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.3Database System Concepts

第一范式第一范式

如果域中元素被认为是不可分的 , 则域称为是原子的 非原子域的例子 :

名字集合 , 复合属性 象 CS101 之类的标识号可以分成若干部分

如果关系模式 R 的所有属性的域都是原子的 , 则 R 称为属于第一范式

非原子值存储复杂并易导致数据冗余 E.g. 每个客户的账户集合 , 以及每个账户的拥有者集合 我们假定所有关系都属于第一范式 ( 参见第 9 章对象关系数据库 )

Page 4: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.4Database System Concepts

第一范式第一范式 ((续续 ))

原子性实际上是关于如何使用域中元素的一种性质 . E.g. 字符串通常认为是不可分的 假设学生具有形如 CS0012 或 EE1127 的字符串学号 若前两个字符可作为系分解出来 , 则学号域不是原子的 .

这样做很不好 : 导致信息编码于应用程序中而不是数据库中 .

Page 5: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.5Database System Concepts

关系数据库设计中易犯的错误关系数据库设计中易犯的错误

关系数据库设计要求我们找到一个 “好的” 关系模式集合 . 一个坏的涉及可能导致 信息的重复 某些信息不能表示

设计目标 : 避免冗余数据 确保属性间联系得以表示 方便检查更新是否破坏了数据库完整性约束

Page 6: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.6Database System Concepts

例如例如 考虑关系模式 :

Lending-schema = (branch-name, branch-city, assets, customer-name, loan-number, amount)

冗余 : branch-name, branch-city, assets 数据对某分行的每笔贷款都要重复一次 浪费空间 使修改操作复杂化 , 可能导致 assets 值的不一致

空值 不能存储没有贷款的分行信息 可以使用空值 , 但空值难于处理 .

Page 7: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.7Database System Concepts

分解分解

将关系模式 Lending-schema 分解成 :

Branch-schema = (branch-name, branch-city,assets)

Loan-info-schema = (customer-name, loan-number, branch-name, amount)

原模式 (R) 的所有属性都必须出现在分解后的 (R1, R2) 中:

R = R1 R2

无损连接分解对模式 R 上的所有可能的关系 r

r = R1 (r) R2 (r)

Page 8: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.8Database System Concepts

有损连接分解例有损连接分解例

分解 R = (A, B)R1 = (A) R2 = (B)

A B

121

A

B

12

rA(r) B(r)

A (r) B (r)A B

1212

Page 9: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.9Database System Concepts

目标目标 — — 设计一个理论设计一个理论 以判断关系模式 R 是否 “好的” 形式 当 R 不是 “好的” 形式时 , 将它分解成模式集合 {R1, R2, ..., Rn}

使得 每个关系模式都是“好的” 形式 分解是无损连接分解

我们的理论基于 : 函数依赖 多值依赖

Page 10: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.10Database System Concepts

函数依赖函数依赖

对合法关系的约束 要求一个属性集的值能唯一确定另一个属性集的值 函数依赖是键概念的推广 .

Page 11: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.11Database System Concepts

函数依赖函数依赖 ((续续 ))

设 R 是一关系模式 , 且有属性集 R , R

函数依赖

在 R 上成立 当且仅当对任意合法关系 r(R), 若 r 的任意两条元组 t1 和 t2 在属性集上的值相同 , 则他们在属性集 上的值也相同 . 即 ,

t1[] = t2 [] t1[ ] = t2 [ ] 例如 : 考虑 r(A,B) 及其下列实例 r.

对此实例 , A B 不成立 , 但 B A 成立 .

1 41 53 7

Page 12: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.12Database System Concepts

函数依赖函数依赖 ((续续 ))

K 是关系模式 R 的超键当且仅当 K R

K 是 R 的候选键当且仅当 K R, 并且 没有 K 使 R

函数依赖使我们可以表达用超键无法表达的约束 . 考虑模式 :

Loan-info-schema = (customer-name, loan-number, branch-name, amount).

我们期望下列函数依赖成立 :

loan-number amountloan-number branch-name

而不期望下列函数依赖成立 :

loan-number customer-name

Page 13: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.13Database System Concepts

函数依赖的使用函数依赖的使用

我们用函数依赖来 : 检查关系在给定函数依赖之下是否合法 .

若关系 r 在函数依赖集 F 下是合法的 , 则称 r 满足 F.

对合法关系集合指定约束 如果 R 上的所有合法关系都满足 F, 则称 F 在 R 上成立 .

注意 : 关系模式的特定实例可能满足一函数依赖 , 但该函数依赖不是在所有合法实例上成立 . 例如 , Loan-schema 的特定实例可能碰巧满足 loan-number customer-name.

Page 14: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.14Database System Concepts

函数依赖函数依赖 ((续续 ))

被所有关系实例都满足的函数依赖称为平凡的 例如

customer-name, loan-number customer-name

customer-name customer-name

一般地 ,若 则 是平凡的

Page 15: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.15Database System Concepts

函数依赖集的闭包函数依赖集的闭包 给定函数依赖集 F, 存在其他函数依赖被 F 逻辑蕴含 .

例如 : 如果 A B 且 B C, 则可推出 A C

被 F 逻辑蕴含的全体函数依赖的集合称为 F 的闭包 . 用 F+ 表示 F 的闭包 .

可利用 Armstrong公理找出 F+ : 若 , 则 ( 自反 )

若 , 则 ( 增广 )

若 且 , 则 ( 传递 )

这些规则是 正确的 (只产生确实成立的函数依赖 )

完备的 (产生所有成立的函数依赖 ).

Page 16: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.16Database System Concepts

例如例如 R = (A, B, C, G, H, I)

F = { A B A CCG HCG I B H}

F+ 的某些成员 A H

从 A B 和 B H 根据传递规则 AG I

用 G 增广 A C 得 AG CG, 再由 CG I 根据传递规则 CG HI

由 CG H and CG I : 可根据函数依赖的定义导出“并规则” , 或 增广 CG I 得到 CG CGI, 增广 CG H 得到 CGI HI, 再利用传递规则

Page 17: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.17Database System Concepts

计算计算 FF++

下列过程计算函数依赖集 F的闭包 :

F+ = Frepeat

for each F+中的函数依赖 f 对 f 应用自反和增广规则 将结果函数依赖加入 F+

for each F+中的一对函数依赖 f1 和 f2 if 若 f1 和 f2 可利用传递规则合并

then 将结果函数依赖加入 F+

until F+ 不再变化

注意 : 后面会介绍完成此任务的另一过程

Page 18: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.18Database System Concepts

函数依赖的闭包函数依赖的闭包 ((续续 ))

可用下列规则进一步简化 F+ 的手工计算 . 若 与 成立 , 则 成立 ( 合并 )

若 成立 , 则 与 成立 ( 分解 )

若 与 成立 , 则 h成立 ( 伪传递 )

以上规则可以从 Armstrong公理推出 .

Page 19: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.19Database System Concepts

属性集的闭包属性集的闭包

给定属性集合 定义 在 F 下的闭包 (记做 +) 为被在 F 下函数决定的属性的集合 :

is in F+ +

计算 + 的算法result := ;while (result 有变化 ) do

for each in F dobegin

if result then result := result end

Page 20: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.20Database System Concepts

属性集闭包例属性集闭包例 R = (A, B, C, G, H, I) F = {A B

A C CG HCG IB H}

(AG)+

1. result = AG

2. result = ABCG (A C and A B)

3. result = ABCGH (CG H and CG AGBC)

4. result = ABCGHI (CG I and CG AGBCH)

AG 是候选键么 ? 1. AG 是超键么 ?

1. AG R?

2. 存在 AG 的子集是超键么 ?

1. A+ R?

2. G+ R?

Page 21: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.21Database System Concepts

属性闭包的用法属性闭包的用法属性闭包算法有多种用途 :

测试超键 : 为检测 是否超键 , 可计算 + 并检查 + 是否包含 R 的所有属性

测试函数依赖 为检测函数依赖 是否成立 (即属于 F+), 只需检查是否 +.

即 , 可计算 +, 并检查它是否包含 .

这个检查简单而高效 , 非常有用 计算 F的闭包

对每个 R, 计算 +, 再对每个 S +, 输出函数依赖 S.

Page 22: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.22Database System Concepts

正则覆盖正则覆盖

函数依赖集合可能有冗余依赖 (即他们能从其他函数依赖推出 ) 例如 : A C 在 {A B, B C, A C} 中是冗余的 函数依赖的某部分可能是冗余的

依赖右部 : {A B, B C, A CD} 可化简为 {A B, B C, A D}

依赖左部 : {A B, B C, AC D} 可化简为 {A B, B C, A D}

直观地说 , F 的正则覆盖是指与 F 等价的“极小的”函数依赖集合 , 没有冗余依赖 , 依赖也没有冗余部分

Page 23: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.23Database System Concepts

无关紧要的属性无关紧要的属性 考虑函数依赖集合 F 及其中的函数依赖 .

如果 A 并且 F 逻辑蕴含 (F – { }) {( – A) }, 则称属性 A 在 中是无关紧要的 .

如果 A 并且 (F – { }) { ( – A)} 逻辑蕴含 F, 则称属性 A 在中是无关紧要的 .

注意 : 上面两种情形中反方向的蕴含平凡成立 , 因为 “较强的”函数依赖总是蕴含较弱的函数依赖

例如 : 给定 F = {A C, AB C } B 在 AB C 中是无关紧要的 , 因为 A C 逻辑蕴含 AB C.

例如 : 给定 F = {A C, AB CD} C 在 AB CD 中是无关紧要的 , 因为即使删除 C 也能推出 A

C

Page 24: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.24Database System Concepts

检测属性是否无关紧要检测属性是否无关紧要

考虑函数依赖集合 F 以及其中的函数依赖 . 为检测属性 A 在 中是否无关紧要

1. 计算在 F 下的 ( – {A})+

2. 检查 (A – {})+ 是否包含 ; 如果是 , 则 A 是无关紧要的 为检测属性 A 在中是否无关紧要

1. 计算在 F’ = (F – { }) { ( – A)} 下的 +

2. 检查 + 是否包含 A; 如果是 , 则 A 是无关紧要的

Page 25: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.25Database System Concepts

正则覆盖正则覆盖

函数依赖集合 F 的一个正则覆盖是满足下列条件的函数依赖集合 Fc

F 逻辑蕴含 Fc 中的所有函数依赖

Fc 逻辑蕴含 F 中的所有函数依赖

Fc 中的函数依赖不含无关紧要的属性 Fc 中的函数依赖的左部都是唯一的

计算 F 的正则覆盖 :repeat

对 F 中的依赖利用合并规则 1 1 和 1 1 替换成 1 1 2

找出含有无关紧要属性的函数依赖 ( 在 或 中 ) 如果找到无关紧要的属性 , 从 中删去

until F 不再变化 注 : 删除某些无关紧要的属性之后 , 可能导致合并规则可应用 , 所以必须

重新应用

Page 26: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.26Database System Concepts

计算正则覆盖例计算正则覆盖例

R = (A, B, C)F = {A BC

B C A BAB C}

合并 A BC 及 A B 成 A BC 集合变成 {A BC, B C, AB C}

A 在 AB C 中是无关紧要的 , 因为 B C 逻辑蕴含 AB C. 集合变成 {A BC, B C}

C 在 A BC 中是无关紧要的 , 因为 A BC 可由 A B 和B C 逻辑推出 .

正则覆盖是 :

A BB C

Page 27: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.27Database System Concepts

范式化的目标范式化的目标 确定一个关系是否属于 “好的” 形式 .

如果关系 R 不属于“好的”形式 , 则将它分解为关系集合 {R1, R2, ..., Rn} 使得 每个关系都属于好的形式 分解是无损连接分解

范式化理论基于 : 函数依赖 多值依赖

Page 28: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.28Database System Concepts

分解分解

将关系模式 Lending-schema 分解成 :

Branch-schema = (branch-name, branch-city,assets)

Loan-info-schema = (customer-name, loan-number, branch-name, amount)

原模式 (R) 的所有属性都必须出现在分解结果 (R1, R2) 中 :R = R1 R2

无损连接分解对模式 R 上的所有可能关系 r

r = R1 (r) R2 (r)

R 分解成 R1 和 R2 是无损连接的当且仅当下列依赖中的至少一个属于 F+: R1 R2 R1

R1 R2 R2

Page 29: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.29Database System Concepts

有损连接分解例有损连接分解例

有损连接分解导致信息丢失 . 例如 : R = (A, B) 分解成

R1 = (A) R2 = (B)

A B

121

A

B

12

rA(r) B(r)

A (r) B (r)A B

1212

Page 30: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.30Database System Concepts

利用函数依赖范式化利用函数依赖范式化

当我们将具有函数依赖集合 F 的关系模式 R 分解成 R1, R2, ..., Rn 时 , 我们希望 无损连接分解 : 否则分解导致信息丢失 .

无冗余 : 关系 Ri 最好属于 Boyce-Codd 范式或第三范式 .

保持依赖 : 令 Fi 是 F+ 中只包含 Ri 中属性的依赖集合 .

分解最好保持依赖 , 即 (F1 F2 … Fn)+ = F+

否则检查更新是否破坏了函数依赖可能需要计算连接 ,代价较大 .

Page 31: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.31Database System Concepts

例例

R = (A, B, C)F = {A B, B C)

R1 = (A, B), R2 = (B, C)

无损连接分解 :

R1 R2 = {B} and B BC

依赖保持 R1 = (A, B), R2 = (A, C)

无损连接分解 :

R1 R2 = {A} and A AB

不保持依赖 ( 不计算 R1 R2 就不能检查 B C)

Page 32: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.32Database System Concepts

检查依赖保持检查依赖保持

为检查依赖 在 R 到 R1, R2, …, Rn的分解中是否得到保持 , 可进行下面的简单测试 ( 设已计算了 F下的属性闭包 ) result =

while (result 有变化 ) dofor each 分解后的 Ri

t = (result Ri)+ Ri

result = result t

若 result 包含中的所有属性 , 则 得到保持 .

需要对 F中所有依赖进行依赖保持的测试 此算法需要多项式时间 , 而计算 F+ 和 (F1 F2 … Fn)

+需要指数时间

Page 33: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.33Database System Concepts

Boyce-Codd Boyce-Codd 范式范式

是平凡的 (i.e., )

是 R 的超键

具有函数依赖集合 F 的关系模式 R 属于 BCNF 当且仅当对 F+ 中所有函数依赖 , 下列两条件至少一个成立 :

Page 34: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.34Database System Concepts

例例

R = (A, B, C)F = {A B

B C}键 = {A}

R 不属于 BCNF

分解成 R1 = (A, B), R2 = (B, C)

R1 与 R2 属于 BCNF

无损连接分解 保持依赖

Page 35: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.35Database System Concepts

检查是否检查是否 BCNFBCNF

为检查非平凡依赖 是否违反 BCNF 的要求1. 计算 +,

2. 检验 +是否包含 R 的所有属性 , 即 , 是否 R 的超键 .

简化的测试 : 为检查具有函数依赖集合 F的关系模式 R 是否属于BCNF, 只需检查 F 中的依赖是否违反 BCNF即可 , 而不需检查F+中的所有依赖 . 可以证明如果 F 中没有违反 BCNF 的依赖 , 则 F+中也没有违反

BCNF 的依赖 .

但是 , 当检查 R 的分解后的关系时仅用 F是错误的 例如 : 考虑 R (A, B, C, D), 具有 F = { A B, B C}

分解 R 到 R1(A,B) 与 R2(A,C,D) F 中的依赖都不是只包含 (A,C,D) 中属性的 , 因此我们可能错误地

认为 R2 满足 BCNF.

事实上 , F+中的依赖 A C 显示 R2 不属于 BCNF.

Page 36: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.36Database System Concepts

BCNF BCNF 分解算法分解算法

result := {R};done := false;compute F+;while (not done) do

if (result 中存在模式 Ri 不属于 BCNF)

then begin令 是 Ri 上的一个非平凡函数依赖

使得 Ri 不属于 F+, 且 = ;

result := (result – Ri) (Ri – ) (, ); end

else done := true;

注意 : 每个 Ri 都属于 BCNF, 且分解是无损连接的 .

Page 37: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.37Database System Concepts

BCNFBCNF 分解例分解例

R = (branch-name, branch-city, assets,customer-name, loan-number, amount)

F = {branch-name assets branch-cityloan-number amount branch-name}

键 = {loan-number, customer-name}

分解 R1 = (branch-name, branch-city, assets)

R2 = (branch-name, customer-name, loan-number, amount)

R3 = (branch-name, loan-number, amount)

R4 = (customer-name, loan-number)

最终分解R1, R3, R4

Page 38: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.38Database System Concepts

检查分解是否属于检查分解是否属于 BCNFBCNF

为检查关系 R 的分解结果 Ri 是否属于 BCNF,

针对 F在 Ri上的限制 (即 , F+中所有只包含 Ri中属性的 FD) 检查 Ri

是否属于 BCNF

或者 : 使用 R 的原始依赖集 F, 但作如下测试 :

– 对每个属性集 Ri, 检查 +是否要么不包含 Ri- 的属性 , 要么包含 Ri 的所有属性 .

若该条件被某个 破坏 , 则可证明依赖 (+ - ) Ri

在 Ri 上成立 , 且违反 BCNF.

利用上面的依赖分解 Ri

Page 39: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.39Database System Concepts

BCNFBCNF 与依赖保持与依赖保持

R = (J, K, L)F = {JK L

L K}两个候选键 = JK and JL

R 不属于 BCNF

R 的任何分解都不会保持JK L

BCNF 分解不总是保持依赖的

Page 40: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.40Database System Concepts

第三范式第三范式 : : 动机动机

存在这样的情况 BCNF 不保持依赖 , 并且 有效地检查更新违反 FD 是重要的

解决方法 : 定义较弱的范式 , 称为第三范式 . 允许出现一些冗余 (从而带来问题 ; 见后例 )

但 FD 可以在单个关系中得到检查 , 不必计算连接 .

总是存在到 3NF 的保持依赖的无损连接分解 .

Page 41: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.41Database System Concepts

第三范式第三范式

关系模式 R 属于第三范式 (3NF) 当且仅当对所有 F+中依赖 :

下列条件中至少一个成立 : 是平凡的 (i.e., )

是 R 的超键 – 中的每个属性 A 包含在 R 的某个候选键中 .

(注 : 各属性可能包含在不同候选键中 )

若一个关系属于 BCNF 则必属于 3NF (因为 BCNF 要求的正是上面的前两个条件 ).

第三个条件是对 BCNF 要求的最小的放宽 , 以便保持依赖 .

Page 42: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.42Database System Concepts

33NF (NF (续续 ))

例 R = (J, K, L)

F = {JK L, L K}

两个候选键 JK and JL

R 属于 3NF

JK L JK 是超键L K K 包含在一候选键中

BCNF 分解导致 (JL) 和 (LK)

检查 JK L 需要连接 上面模式存在一些冗余 等价于书上的例子 :

Banker-schema = (branch-name, customer-name, banker-name)

banker-name branch name

branch name customer-name banker-name

Page 43: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.43Database System Concepts

检查是否属于检查是否属于 3NF3NF

优化 : 只需检查 F 中的 FD, 而不必检查 F+中的所有 FD.

对每个依赖 , 利用属性闭包来检查 是否超键 .

如果 不是超键 , 必须检查中的每个属性是否包含在 R 的某个候选键中 这个检查较昂贵 , 因为它涉及求候选键 检查 3NF 是 NP-hard 的 有趣的是 , 分解到第三范式可以在多项式时间内完成

Page 44: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.44Database System Concepts

33NF NF 分解算法分解算法令 Fc 是 F 的正则覆盖 ;

i := 0;for each Fc中的函数依赖 do

if 没有模式 Rj (1 j i) 包含 then begin

i := i + 1;Ri :=

endif 没有模式 Rj (1 j i) 包含 R 的候选键

then begini := i + 1;Ri := R 的任意候选键 ;

end return (R1, R2, ..., Ri)

Page 45: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.45Database System Concepts

33NF NF 分解算法分解算法 ((续续 ))

上述算法确保 :

每个关系模式 Ri 属于 3NF

分解是保持依赖的和无损连接的 正确性证明在本文件末尾 (click here)

Page 46: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.46Database System Concepts

例例

关系模式 :

Banker-info-schema = (branch-name, customer-name,banker-name, office-number)

本关系模式上的函数依赖包括 :banker-name branch-name office-numbercustomer-name branch-name banker-name

键 :

{customer-name, branch-name}

Page 47: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.47Database System Concepts

对对 Banker-info-schemaBanker-info-schema 应用应用 3NF3NF

算法中的 for 循环使下列模式包含在分解中 :

Banker-office-schema = (banker-name, branch-name, office-number)

Banker-schema = (customer-name, branch-name, banker-name)

由于 Banker-schema 包含 Banker-info-schema 的候选键 , 分解过程到此为止 .

Page 48: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.48Database System Concepts

BCNFBCNF 与 与 3NF3NF 的比较的比较

总是可以将一个关系分解到 3NF 并且满足 分解是无损的 保持依赖

总是可以将一个关系分解到 BCNF 并且满足 分解是无损的 但可能不保持依赖 .

Page 49: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.49Database System Concepts

BCNFBCNF 与 与 3NF3NF 的比较的比较 ((续续 ))

Jj1

j2

j3

null

Ll1

l1

l1

l2

Kk1

k1

k1

k2

属于 3NF 但不属于 BCNF 的模式有下面的问题 信息重复 (e.g., 联系 l1, k1)

需要使用空值 (e.g., 表示联系 l2, k2 , 这里没有对应的 J 值 ).

因 3NF 的冗余引起的问题 R = (J, K, L)

F = {JK L, L K}

Page 50: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.50Database System Concepts

设计目标设计目标

关系数据库设计的目标是 : BCNF.

无损连接 .

依赖保持 .

如果不能达到这些 , 也可接受 缺少依赖保持 因 3NF引起的冗余

除了超键之外 , SQL 并没有提供直接声明函数依赖的方法 .

可以通过断言声明 FD, 但检测代价大 . 因此即使我们有一个保持依赖的分解 , 用 SQL 我们也不能有效地

检测左部不是键的函数依赖 .

Page 51: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.51Database System Concepts

跨关系检测跨关系检测 FDFD

如果分解不保持依赖 , 我们可以为 Fc中每个未被保持的依赖 定义实视图

实视图定义为分解关系的连接在 上的投影 许多新一代数据库系统支持实视图 , 并且数据库系统负责当关系

更新时对视图的维护 .

FD 成为实视图上的候选键 .

程序员没有额外的更新时维护冗余数据一致性的编码负担 空间开销 : 保存实视图 时间开销 : 当关系更新时需要维护实视图

Page 52: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.52Database System Concepts

多值依赖多值依赖 有时属于 BCNF 的模式仍然未充分规范化 考虑数据库

classes(course, teacher, book)其中 (c,t,b) classes 意思是教师 t 可以教课程 c, 而 b 是需用于课程 c的教材

数据库将为每门课程列出能讲授该课程的教师的集合 , 以及需用的书的集合 ( 不管谁讲授该课 ).

Page 53: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.53Database System Concepts

由于没有非平凡依赖 , (course, teacher, book) 是唯一的键 , 因此该关系模式属于 BCNF

插入异常 – 如果 Sara 是能教数据库的新教师 , 必须插入两条元组

(database, Sara, DB Concepts)(database, Sara, Ullman)

course teacher book

databasedatabasedatabasedatabasedatabasedatabaseoperating systemsoperating systemsoperating systemsoperating systems

AviAviHankHankSudarshanSudarshanAviAvi Jim Jim

DB ConceptsUllmanDB ConceptsUllmanDB ConceptsUllmanOS ConceptsShawOS ConceptsShaw

classes

Page 54: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.54Database System Concepts

因此 , 最好将 classes 分解成 :

course teacher

databasedatabasedatabaseoperating systemsoperating systems

AviHankSudarshanAvi Jim

teaches

course book

databasedatabaseoperating systemsoperating systems

DB ConceptsUllmanOS ConceptsShaw

text

我们将看到这两个关系都属于第四范式 (4NF)

Page 55: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.55Database System Concepts

多值依赖多值依赖 (MVD)(MVD)

设有关系模式 R, 令 R 及 R. 多值依赖

在 R 上成立当且仅当在任意合法关系 r(R) 中 , 对所有满足 t1[] = t2 []的元组对 t1 和 t2, 必存在元组 t3 和 t4 使得:

t1[] = t2 [] = t3 [] = t4 [] t3[] = t1 [] t3[R – – ] = t2[R – – ] t4[ ] = t2[] t4[R – – ] = t1[R – – ]

Page 56: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.56Database System Concepts

MVD (MVD (续续 ))

用表来表示

Page 57: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.57Database System Concepts

例例

设关系模式 R 的属性集合被分成三个非空子集Y, Z, W

称 Y Z (Y 多值决定 Z)当且仅当对所有可能的关系 r(R), 若< y1, z1, w1 > r 及 < y2, z2, w2 > r

则< y1, z1, w2 > r 及 < y1, z2, w1 > r

注意由于 Z和W 的行为完全对称 , 若 Y W 则 Y Z

Page 58: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.58Database System Concepts

例例 ((续续 ))

在前面的例子中 :

course teachercourse book

上述形式定义表达了这种概念 : 给定 Y (course) 的特定值, 则有一个 Z (teacher) 值的集合和一个 W (book) 值的集合与之相关联 , 而这两个集合在某种意义上是相互独立的 .

注 : 若 Y Z 则 Y Z

事实上我们有 ( 用前面的表示法 ) Z1 = Z2

所以此命题成立 .

Page 59: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.59Database System Concepts

多值依赖的用法多值依赖的用法

有两种使用多值依赖的方法 :

1. 检测关系以确定他们在给定函数依赖和多值依赖集合之下是否合法

2. 对合法关系集合声明约束 . 这样我们就只关心满足给定函数依赖和多值依赖的关系 .

若关系 r 不满足给定多值依赖 , 我们可以通过增加元组来构造满足该多值依赖的关系 r.

Page 60: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.60Database System Concepts

MVDMVD 理论理论

根据多值依赖的定义 , 可导出下列规则 : 若 , 则

即函数依赖是多值依赖的特例 D的闭包 D+ 是 D 逻辑蕴含的所有函数依赖和多值依赖的集合 .

可根据函数依赖与多值依赖的形式定义来从 D 计算 D+.

我们只对在实践中较常见的简单多值依赖可用这样的推理 对于复杂的依赖 , 最好利用一套推理规则 ( 见附录 C) 来对依赖集合进行推理 .

Page 61: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.61Database System Concepts

第四范式第四范式

关系模式 R 关于函数依赖及多值依赖集合 D 属于 4NF 当且仅当对 D+中所有形如 的多值依赖 , 其中 R 且 R, 下列条件中至少一个成立 : 是平凡的 (i.e., 或 = R)

是模式 R 的超键 若关系属于 4NF 则它必属于 BCNF

Page 62: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.62Database System Concepts

多值依赖的限制多值依赖的限制

D在 Ri 上的限制是指由下列组成的集合 Di

所有 D+中只包含 Ri 的属性的函数依赖 所有形如

( Ri)

的多值依赖 , 其中 Ri 且 属于 D+

Page 63: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.63Database System Concepts

44NFNF 分解算法分解算法

result: = {R};done := false;compute D+;令 Di 表示 D+ 在 Ri 上的限制

while (not done) if (在 result 中有不属于 4NF 的模式 Ri) then begin

令 是在 Ri 上成立的一个非平凡多值依赖 , 它使得 Ri 不属于 Di, 并且 ;

result := (result - Ri) (Ri - ) (, ); end else done:= true;

注 : 每个 Ri 属于 4NF, 且分解是无损连接的

Page 64: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.64Database System Concepts

例例 R =(A, B, C, G, H, I)

F ={ A B

B HI

CG H }

R 不属于 4NF, 因为 A B 且 A 不是 R 的超键 分解

a) R1 = (A, B) (R1 属于 4NF)

b) R2 = (A, C, G, H, I) (R2 不属于 4NF)

c) R3 = (C, G, H) (R3 属于 4NF)

d) R4 = (A, C, G, I) (R4 不属于 4NF)

由于 A B 且 B HI, A HI, A I

e) R5 = (A, I) (R5 属于 4NF)

f)R6 = (A, C, G) (R6 属于 4NF)

Page 65: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.65Database System Concepts

进一步的范式进一步的范式

join dependencies generalize multivalued dependencies lead to project-join normal form (PJNF) (also called fifth normal

form)

A class of even more general constraints, leads to a normal form called domain-key normal form.

Problem with these generalized constraints: i hard to reason with, and no set of sound and complete set of inference rules.

Hence rarely used

Page 66: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.66Database System Concepts

数据库设计全过程数据库设计全过程

假设给定了模式 R R 可能是经转换 E-R图到表而生成的 .

R 可能是单个包含所有属性的关系 ( 称为全关系 ).

规范化将 R 分解成较小的关系 .

R 可能是某种特定设计的结果 , 然后再测试 /转换成范式 .

Page 67: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.67Database System Concepts

ERER 模型与规范化模型与规范化

当 E-R图是很仔细地设计 , 正确地标识所有实体 , 则从 E-R图生成的关系应该不需要进一步的规范化 .

但是 , 在现实 ( 不完善的 ) 设计中可能存在从实体的非键属性到其他属性的 FD

例如 : employee 实体具有属性 department-number 和 department-address, 以及 FD department-number department-address 好的设计应该将 department 作为实体

从联系集的非键属性引出 FD 是可能的 , 但极少 --- 多数联系是二元的

Page 68: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.68Database System Concepts

全关系方法全关系方法

悬空元组 – 计算连接时 “消失”的元组 .

令 r1 (R1), r2 (R2), …., rn (Rn) 是一个关系集合 关系 ri 的元组 r 称为悬空元组 , 如果 r 不属于关系 :

Ri (r1 r2 … rn)

关系 r1 r2 … rn 称为全关系 , 因为它包含了由下式定义的“属性全集”中的所有属性 R1 R2 … Rn

如果数据库中允许出现悬空元组 , 则我们可能宁愿从给定属性集合合成若干范式化模式 , 而不是分解全关系 .

Page 69: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.69Database System Concepts

全关系方法全关系方法 (( 续续 ))

悬空元组在实际数据库应用中可能出现 .

他们代表不完全的信息 例如 : 可能想将关于贷款的信息分解成 :

(branch-name, loan-number)

(loan-number, amount)

(loan-number, customer-name)

全关系需要用到空值 , 并且具有悬空元组

Page 70: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.70Database System Concepts

全关系方法全关系方法 ((续续 ))

特定分解定义了数据库中可接受的一个不完全信息的限制性形式 . 上例中至少需要 customer-name, branch-name 或 amount 之一以便输入贷款号而不用空值

排除没有适当 loan-number 而存储 customer-name, amount 的情况(由于它是键 , 不得为空 !)

唯一角色假设 : 全关系要求每个属性名在数据库中具有唯一的意义 e.g. customer-name, branch-name

重用属性名在 SQL 中是很自然的 , 因为关系名可作为前缀来避免名字的歧义

Page 71: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.71Database System Concepts

为性能而反规范化为性能而反规范化

为提高性能可能使用非规范化的模式 例如 : 一道显示 customer-name 与 account-number 及 balance 需将 account 和 depositor 连接

其他做法 1: 使用包含 account 以及 depositor 的所有上述属性的反规范化关系 查找迅速 额外空间以及额外更新执行时间 程序员的额外编码工作以及更多出错可能性

其他做法 2: 使用如下定义的实视图 account depositor 优缺点同上 , 除了程序员的额外编码工作和避免可能的错误

Page 72: 第 7 章: 关系数据库设计

©Silberschatz, Korth and Sudarshan7.72Database System Concepts

其他设计问题其他设计问题

有些数据库设计问题不能被规范化解决 应避免的坏的数据库设计例 :

不用 earnings(company-id, year, amount), 而是用 具有同样模式 (company-id, earnings) 的 earnings-2000, earnings-

2001, earnings-2002, 等等 . 这属于 BCNF, 但使得跨年度查询很困难 , 并且每年都需要新表

company-year(company-id, earnings-2000, earnings-2001, earnings-2002)

也属于 BCNF, 但同样使跨年度查询很困难 , 并且每年都需要新表 .

这是一个 crosstab 的例子 , 将属性值作为了列名 可用于 spreadsheets, 以及数据分析工具

Page 73: 第 7 章: 关系数据库设计

End of ChapterEnd of Chapter