(数据库原理与应用)关系数据库设计 -8(持续更新中)
1. 函数依赖
简介
在关系数据库中,函数依赖(Functional Dependency)是一种重要的概念,用于描述一个属性或属性集合对于另一个属性或属性集合的依赖关系。函数依赖定义了一个属性的值如何依赖于另一个属性的值。函数依赖通常用箭头符号 "->" 表示。
具体来说,如果在一个关系中,对于给定的属性或属性组合,属性A的值唯一地决定了属性B的值,那么我们可以表示为 A -> B。这意味着在给定关系中,对于相同的A值,B值总是相同的。
例如,考虑一个包含"学生ID"、"学生姓名"和"学生年龄"的关系表。如果我们有一个函数依赖 "学生ID -> 学生姓名",那么这意味着在同一个学生ID下,学生姓名的值是唯一的,即一个学生ID对应一个学生姓名。这是一种单一属性的函数依赖。
函数依赖与超码和候选码之间的关系
- 如果一个属性集合α函数依赖于另一个属性集合β,那么β必定是一个超码(可能是候选码),因为它能够唯一确定α的值。
- 例如,如果学生ID → 学生姓名,则学生ID是一个候选码或超码,而学生姓名是一个函数依赖于学生ID的属性。
平凡的函数依赖
平凡的函数依赖是一种特殊的函数依赖,其特点是决定属性集合(α)包含了依赖属性集合(β)。换句话说,在平凡的函数依赖中,依赖属性集合β是决定属性集合α的子集。
具体来说,如果一个函数依赖α → β是平凡的,那么α和β必定相同。 这意味着依赖属性集合β中的属性在决定属性集合α中,或者可以说决定属性集合α包含了依赖属性集合β。这样的函数依赖通常不会提供有用的信息,因为它没有描述属性之间的真正依赖关系,只是确认了某些属性自身的存在。
例如,考虑以下关系模式(表)R:
R = {学生ID, 学生姓名, 学生ID}
在这种情况下,如果存在函数依赖学生ID → 学生ID,这被认为是一个平凡的函数依赖,因为它仅确认学生ID属性自身的存在,没有提供任何额外的信息。
平凡的函数依赖通常被视为没有实际用途,因为它们没有帮助我们理解数据表中的属性之间的有意义的依赖关系。在数据库设计和规范化过程中,通常会考虑并强调非平凡的函数依赖,这些依赖关系提供了有关数据的更有用和有意义的信息。
函数依赖集
函数依赖集是所有属性之间的函数依赖关系的集合。函数依赖集用于描述在一个关系模式(表)中,一个属性集合如何依赖于另一个属性集合。
例如,考虑以下关系模式R,包括属性A、B、C、D:
R = {A, B, C, D}
一个可能的函数依赖集可以是:
- A → B:属性A的值决定属性B的值。
- C, D → A:属性C和D的值共同决定属性A的值。
- B → C, D:属性B的值决定属性C和D的值。
-
如果一个关系 r 没有违反函数依赖集 F, 那么称
关系 r 满足函数依赖集 F ( r satisfies F )
-
如果关系模式 R 的所有关系都满足函数依赖集 F, 那么称
函数依赖集F 在关系模式 R 上成立 ( F holds on R )
函数依赖集的等价性
设 F1 和 F2 是两个函数依赖集,如果由F1 可以推出 F2 的所有函数依赖,由F2 也可以推出 F1 的所有函数依赖,就说 F1 和 F2 是等价的
例如:
{A → B, B → C}
和
{A → B, B → C, A→C} 是等价的
2.属性集的闭包
简介
属性集的闭包用于描述一个属性集合经过一系列函数依赖操作后所能推导出的属性集合。属性集的闭包通常用符号来表示,通常写作 {X}^+,其中X是初始属性集合。
闭包操作通过不断应用函数依赖规则来确定一个属性集合中可以推导出的所有属性。以下是函数依赖规则的一些示例:
- 反身性规则:如果A包含在X中,那么A也包含在{X}^+中。
- 广泛性规则:如果X → Y,那么{X}^+中也包含Y。
- 传递规则:如果X → Y,Y → Z,那么{X}^+中包含Z。
通过这些规则,可以计算出属性集合的闭包,以了解它们之间的依赖关系。闭包是一个属性集合,其中包含了X及其可以推导出的所有属性。这对于数据库设计和规范化非常重要,因为它帮助设计师确定一个属性集合是否包含其他属性的决定属性,从而可以更好地组织数据库表。
例如,假设有一个关系模式R = {A, B, C, D},并且有以下函数依赖:
- A → B
- B → C
如果我们计算{A}^+,我们可以得到{A, B, C},因为A决定了B,B又决定了C。这表示A的闭包包括A、B和C。这对于确定属性的超码和候选码以及数据库规范化都非常有用。
计算属性集的闭包的算法
result := α;
不断使用 F 中的函数依赖,把 result 能决定的其他属性都加进 result,直到不能再添加属性到 result 为止,输出 result 作为α^+
R = (A, B, C, G, H, I)
F = { A → B
A → C
CG → H
CG → I
B → H }
计算 (AG)^+
result = AG
A → B -----------result = ABG
A → C ----------- result = ABCG
CG → H ----------- result = ABCGH
CG → I ----------- result = ABCGHI
B → H ----------- result = ABCGHI
result 已经包含了全部属性, 可以停止
计算步骤解释
初始闭包:将{AG}加入到闭包中,即{AG}^+ = {AG}。
使用广泛性规则(规则2):检查F中的函数依赖,看是否有其他属性可以添加到闭包中。
- 根据F中的函数依赖 A → B,我们可以将B添加到闭包中,因为A → B → H(根据 F 中的 B → H)。
- 根据F中的函数依赖 A → C,我们可以将C添加到闭包中。
现在,{AG}^+ = {AG, B, C}。
再次使用广泛性规则:继续检查F中的函数依赖,看是否有其他属性可以添加到闭包中。
- 根据F中的函数依赖 CG → H,由于C已经在闭包中,我们可以将H添加到闭包中。
- 根据F中的函数依赖 CG → I,由于C已经在闭包中,我们可以将I添加到闭包中。
现在,{AG}的闭包为{AG, B, C, H, I}。
- 再次使用广泛性规则:检查其他函数依赖,但在这种情况下,没有其他函数依赖可以应用,因为所有的函数依赖都已经包含在闭包中。
最终,{AG}的闭包是{AG, B, C, H, I}。这表示属性集合{AG}经过给定函数依赖集F的作用后,能推导出的所有属性。这对于数据库规范化和属性依赖分析非常有用。
属性闭包的作用
- 判断一个属性集是否超码
要判断 α 是不是 R 的超码,只要看 α^+ 是不是包含 R
- 判断一个函数依赖是否成立
要判断 α → β 是不是成立,只要看β是否包含与α^+
- 简便地计算函数依赖集的闭包
转载自:https://juejin.cn/post/7296297674130702348