数据库-函数依赖

数据库-函数依赖

Lucas

函数依赖的定义和类型

关系模式的形式化定义

关系模式的形式化定义是指关系模式由五部分组成, 是一个五元组, 形如 R(U,D,DOM,F)R (U,D,DOM,F)

  • RR 表示关系名
  • UU 表示组成该关系的属性名集合
  • DD 表示属性组 U 中属性所来自的域
  • DOMDOM 表示属性到域的映射集合
  • FF 表示属性间数据的依赖关系集合

函数依赖的定义

函数依赖是数据依赖的一种, 函数 Y=f(X)Y=f(X) 表示的是, 给定一个 XX, 会有一个 YY 与之对应
即 XX 决定 YY, YY 依赖于 XX, 记作:X→YX\to Y

关系数据库中, 讨论函数依赖, 更注重语义上的关系.

例如:Sname=f(Sno)Sname=f(Sno) 表示只要给出一个具体的 学号学号 就会有一个 姓名姓名 与之对应, 即学号决定姓名, 或者姓名依赖于学号. R(U)R(U) 是属性集 UU 上的关系模式, XX 和 YY 是 UU 的子集.

可见函数依赖讨论的是属性之间的依赖关系.

  • 函数依赖不是指关系模式 RR 的所有关系实例均要满足的约束条件.
  • 人只能通过语义来确定函数依赖.
  • 属性间的函数依赖与属性间的联系相关.
    如果属性 XX 和 YY 是"1:1"的联系或者 “1:n” 的联系, 则存在函数依赖; 如果 XX 和 YY 之间是 “m:n” 联系, 则不存在函数依赖.
  • 若 X→YX\to Y 且 Y→XY\to X, 则记为 X↔YX\leftrightarrow Y
  • 若 YY 不依赖于 XX, 记作:x↛Yx\not\to Y

函数依赖的类型

平凡依赖和非平凡依赖

在关系模式中, 对于 UU 的子集 XX 和 YY, 如果 X→YX\to Y

  • 若 Y⊈XY\not\subseteq X, 则称 X→YX\to Y 是非平凡函数依赖
  • 若 Y⊆XY\subseteq X, 则称 X→YX\to Y 是平凡函数依赖.

例如:X→∅X\to \varnothing 、X→XX\to X 是非平凡依赖.

举例:
平凡函数依赖:学号→成绩学号\to 成绩
非平凡函数依赖:{姓名,性别}→姓名\{姓名,性别\}\to 姓名

完全函数依赖和部分函数依赖

在关系模式 R(U)R(U) 中, 如果 X→YX\to Y 并且对于 XX 的任何一个真子集 X′X', 都有 X′↛YX'\not\to Y, 则称 YY 对 XX 完全函数依赖, 记作:X→FYX\overset{F}\to Y

若 X→YX\to Y, 且存在 XX 的某一真子集 X′X', 使得 X′→YX'\to Y, 则称 YY 对 XX 部分函数依赖, 记作:X→PYX\overset{P}\to Y

举例:
部分函数依赖:{学号,姓名}→成绩\{学号,姓名\}\to 成绩
完全函数依赖:{班级,成绩}→成绩\{班级,成绩\}\to 成绩

传递函数依赖

在关系模式 R(U)R(U) 中, XX、YY、ZZ 是 RR 的 3 个不同的属性或属性组, 如果 X→Y,(Y不是X的子集)X\to Y,(Y 不是 X 的子集) 且 Y↛XY\not\to X, Y→ZY\to Z, Z∉YZ\not\in Y, 则称 ZZ 对 XX 为传递函数依赖:

传递函数依赖要求 YY:

  • YY 不能决定 XX (Y↛XY\not\to X)
    如果 Y→XY\to X ,则 Y↔XY\leftrightarrow X , XX YY 等价, 所以 X→ZX\to Z 就变成了直接依赖.
  • YY 不是 XX 的子集
    如果 YY 是 XX 的子集, 就变成了 X{Y,...}→ZX\{Y,...\}\to Z ,成了部分依赖.

举例:
学号→专业→专业人数学号\to 专业 \to 专业人数
传递依赖是一种间接传递 (如果不知道学生专业就不知道专业人数)

FD 的逻辑蕴涵和公理系统

FD 指的是 Functional Dependency 函数依赖

FD 的逻辑蕴涵

FD 的逻辑蕴涵指的是在一直的函数依赖集 F 中判断是否蕴涵着未知的函数依赖

函数依赖集 F 的闭包

被 F 逻辑蕴涵的所有函数依赖 FD 全体构成的集合叫做函数依赖集 F 的闭包, 记为: F+F^+

F+={X→Y∣F⇒X→Y}F^+ = \{X\to Y\mid F\Rightarrow X\to Y \}

FD 的公理系统

为了从 FF 中求出 F+F^+ , 尤其是根据已知的 FD 判断一个未知的 FD 是否成立, 或者求候选键, 就会用到 FD 的公理系统, 规则说明如下

  • 自反律: 若在 RR 中有 Y⊆XY\subseteq X , 则 X→YX\to Y 在 RR 上成立, 并且蕴涵于 FF 之中.
  • 传递率: 若 FF 中的 X→YX\to Y 和 Y→XY\to X 在 RR 上成立, 则 X→ZX\to Z 在 RR 上成立, 并且蕴涵于 FF 之中.
  • 增广率: 若 FF 中的 X→YX\to Y 在 RR 上成立, 则 XZ→YZXZ\to YZ 在 RR 上也成立, 并且蕴涵于 FF 之中.

除上述三条推理规则外, 下面给出可由这 3 条规则推到哦出的 3 条推论

  • 合并律: 若 X→YX\to Y, X→ZX\to Z, 则有 X→YZX\to YZ.
  • 分解律: 若 X→YZX\to YZ, 则有 X→YX\to Y, X→ZX\to Z.
  • 伪传递率: 若 X→YX\to Y, YW→ZYW\to Z, 则有 XW→ZXW\to Z.

属性集闭包

推导出来的, 属性 XX 能决定的所有属性集合叫 XX 属性的闭包, 记作 X+X^+

求属性集闭包

前提: 有限的属性集合 UU, UU 的子集 XX, 以及在 UU 上成立的 FDFD 集 FF , 求 XX 关于 FF 的闭包 X+X^+

具体步骤如下:

  1. X(0)=XX(0)=X
  2. X(i+1)=X(i)AX(i+1)=X(i)A, 其中 AA 满足以下条件:
    1. 在 FF 中寻找尚未使用过的
    2. FDFD 左边是 X(i)X(i) 的子集
  3. 判断 X(i+1)?=X(i)X(i+1)?=X(i), 若相等, 转到下一步, 否则返回上一步继续寻找
  4. 输出 X(i)X(i), 即 X+X^+

对于步骤 3 的判断, 以下 4 种方法是等价的:

  1. X(i+1)=X(i)X(i+1)=X(i)
  2. X(i)X(i) 中包含了全部属性
  3. FF 中未使用的 FDFD 左侧 找不到 X(i)X(i) 的子集
  4. FF 中未使用的 FDFD 右侧 找到的都是 X(i)X(i) 的子集

举例:
现在有关系模式 R(U,F)R(U,F), 其中 U={A,B,C,D,E,I}U=\{A,B,C,D,E,I\}, F={A→D,AB→I,BI→E,CD→I,E→C}F=\{A\to D,AB\to I,BI\to E,CD\to I,E\to C\}, 求 (AE)+(AE)^+
解:
令 X={AE}X=\{AE\}, X(0)=X={AE}X(0)=X=\{AE\}

在 FF 中找出左边是 AEAE 子集的函数依赖, 其结果是: A→DA\to D, E→CE\to C.
所以, X(1)=X(0)DC=AEDCX(1)=X(0)DC=AEDC (顺序无所谓)
判断 X(1)≠X(0)X(1)\neq X(0), 继续寻找

在 FF 中未使用的 FDFD 找出左边是 AEDCAEDC 子集的函数依赖, 其结果是: CD→ICD\to I.
所以, X(2)=X(1)I=AEDCIX(2)=X(1)I=AEDCI, 显然 X(2)≠X(1)X(2)\neq X(1) 继续寻找.

在 FF 中未使用的 FDFD 找出左边是 AEDCIAEDCI 子集的函数依赖, 发现没有了, 停止寻找, 输出 X(i)=AEDCIX(i)=AEDCI

FF 的最小依赖集 FmF_m

如果函数依赖集 FF 满足一下条件, 则称为最小依赖集, 记为 FmF_m

  • FF 的右侧都是单属性
  • FF 中不存在多余依赖 (不存在任何依赖可以被其余依赖推出来)
  • FF 的左侧不存在多余属性 (左侧删除任何属性都会导致依赖不成立)

每个函数依赖集 FF 都与它的最小依赖集 FmF_m 等价

具体步骤:

  1. 右边属性单一化
  2. 去掉各依赖左边多余的属性
  3. 去掉多余依赖

为什么要先去掉各依赖左边多余的属性?
因为如果先去掉多余依赖后, 去掉左边多余属性之后, 还有可能会出现新的冗余依赖.

举例:
设有关系模式 RR, 其依赖集为:
F={AB→C,C→A,BC→D,ACD→B,D→EG,BE→C,CG→BD,CE→AG}F=\{AB\to C,C\to A,BC\to D,ACD\to B,D\to EG,BE\to C,CG\to BD,CE\to AG \}
求 FF 等价的最小依赖集 FmF_m
解:

  1. 将右边的属性单一化
    D→EG⇒D→E,D→GD\to EG \Rightarrow D\to E,D\to G
    CG→BD⇒CG→B,CG→DCG\to BD \Rightarrow CG\to B,CG\to D
    CE→AG⇒CE→A,CE→GCE\to AG \Rightarrow CE\to A, CE\to G
    得到 F={AB→C,C→A,BC→D,ACD→B,D→E,D→G,BE→C,CG→B,CG→D,CE→A,CE→G}F=\{AB\to C,C\to A,BC\to D,ACD\to B,D\to E,D\to G,BE\to C,CG\to B,CG\to D,CE\to A,CE\to G \}

  2. 去掉左边多余属性

    1. 检查 AB→CAB\to C
      检查 AA 是否冗余: 去掉 AA, 算 B+B^+, B+=BB^+=B, 不含 CC, 所以 AA 不冗余
      检查 BB 是否冗余: 去掉 BB, 算 A+A^+, A+=AA^+=A, 不含 CC, 所以 BB 不冗余
      结论: AB→CAB\to C 左部无冗余
    2. 同理检查 BC→DBC\to D
      C+=CAC^+=CA, 不含 DD, 所以 BB 不冗余
      B+=BB^+=B, 不含 DD, 所以 CC 不冗余
      结论: BC→DBC\to D 左部无冗余
    3. ACD→BACD\to B
      (CD)+=CDAEGB(CD)^+=CDAEGB, 含 BB, 说明 AA 是冗余属性
      (AD)+=ADEG(AD)^+=ADEG, 不含 BB, 所以 CC 不冗余
      (AC)+=AC(AC)^+=AC, 不含 BB, 所以 DD 不冗余
      结论: ACD→BACD\to B 应该移除冗余属性得到 CD→BCD\to B
    4. BE→CBE\to C
      B+=BB^+=B, 不含 CC, 所以 EE 不冗余
      E+=EE^+=E, 不含 CC, 所以 BB 不冗余
      结论: BE→CBE\to C 左部无冗余
    5. CG→BCG\to B
      C+=CAC^+=CA, 不含 BB, 所以 GG 不冗余
      G+=GG^+=G, 不含 BB, 所以 CC 不冗余
      结论: CG→BCG\to B 左部无冗余
    6. CG→DCG\to D
      C+=CAC^+=CA, 不含 DD, 所以 GG 不冗余
      G+=GG^+=G, 不含 DD, 所以 CC 不冗余
      结论: CG→DCG\to D 左部无冗余
    7. CE→ACE\to A
      C+=CAC^+=CA, 含 AA, 说明 EE 是冗余属性
      E+=EE^+=E, 不含 AA, 所以 CC 不冗余
      结论: CE→ACE\to A 应该移除冗余属性得到 C→AC\to A, 已经存在 C→AC\to A, 所以需要移除, 或者在后面移除冗余依赖的时候移除也可以.
    8. CE→GCE\to G
      C+=CAC^+=CA, 不含 GG, 所以 EE 不冗余
      E+=EE^+=E, 不含 GG, 所以 CC 不冗余
      结论: CE→GCE\to G 左部无冗余

    最后得到: F={AB→C,C→A,BC→D,CD→B,D→E,D→G,BE→C,CG→B,CG→D,CE→G}F=\{AB\to C,C\to A,BC\to D,CD\to B,D\to E,D\to G,BE\to C,CG\to B,CG\to D,CE\to G \}

  3. 去掉冗余依赖
    一眼看过去, 可以直接判断本题的, 左侧仅有一个属性的 FD 无冗余依赖

    1. 检查 AB→CAB\to C 是否冗余, 暂时移除 AB→CAB\to C
      计算 (AB)+=AB(AB)^+=AB
      结论: 不含 CC, AB→CAB\to C 不冗余
    2. 检查 BC→DBC\to D 是否冗余, 暂时移除 BC→DBC\to D
      (BC)+=BCA(BC)^+=BCA
      结论: 不含 DD, BC→DBC\to D 左部无冗余
    3. CD→BCD\to B, 暂时移除 CD→BCD\to B
      (CD)+=CDAEGB(CD)^+=CDAEGB
      结论: 含 BB, 所以是冗余依赖, 直接移除
    4. BE→CBE\to C, 暂时移除 BE→CBE\to C
      (BE)+=BE(BE)^+=BE
      结论: 不含 CC, BE→CBE\to C
    5. CG→BCG\to B, 暂时移除 CG→BCG\to B
      (CG)+=CGADE(CG)^+=CGADE (这里因为前面移除了 CD→BCD\to B 所以闭包里就没有 BB 了)
      结论: 不含 BB, 所以 CG→BCG\to B 不冗余
    6. CG→DCG\to D
      (CG)+=CGABDE(CG)^+=CGABDE
      结论: 含 DD, 所以是冗余依赖, 直接移除
    7. CE→GCE\to G
      (CE)+=CEA(CE)^+=CEA
      结论: 不含 GG, 所以 CE→GCE\to G 不冗余

最终得到: F={AB→C,C→A,BC→D,D→E,D→G,BE→C,CG→B,CE→G}F=\{AB\to C,C\to A,BC\to D,D\to E,D\to G,BE\to C,CG\to B,CE\to G \}

  • 最小覆盖 (最小依赖集) 的化简过程通常是迭代式、逐步更新依赖集的:
    每做一次删除, 依赖集就更新一次; 后续所有闭包计算都基于当前最新的依赖集.

  • FmF_m 不是唯一的

求候选码(键)

能函数决定全部属性称为一个 超键
极小超键就是 候选键, 是不能再删减属性的超键
不能说 “最小超键” 因为 候选键 不止一个

这里只介绍 2 种计算方法: 图论判定法 和 多属性依赖集求解解法

在计算之前, 需要先给属性进行分类:

  • L类: 仅出现在 FF 的函数依赖左边的属性
  • R类: 仅出现在 FF 的函数依赖右边的属性
  • N类: 在 FF 的函数依赖左右均未出现的属性
  • LR类: 在 FF 的函数依赖左右均出现的属性

在分类的时候要从关系本身一个属性一个属性在函数依赖里面找, 不要直接在函数依赖里面找

图论判定法

如果依赖集等价的最小依赖集左边是单属性, 可以使用图论判定法求出所有候选键
我们需要画出函数依赖图, 函数依赖图是一个有序二元组 (R,F)(R,F), RR 中所有属性都是结点, 所有依赖都是有向边

  1. 引入线/引出线:若结点 AA 到 AA 是连接, 则边 Ai,AjA_i,A_j 是 AiA_i 引出线, 是 AjA_j 引入线
  2. 原始点:只有引出线而无引入线旳结点
  3. 终结点:只有引入线而无引出线的结点
  4. 途中点:既有引入线又有引出线的结点
  5. 孤立点:既无引入线又无引出线的结点
  6. 关键点:原始点和孤立点都称为关键点
  7. 关键尿性:关键点对应属性
  8. 独立回路:不能被其他结点到达钓回路

求候选键具体步骤如下:

  1. 求出F最小依赖集 FmF_m
  2. 构造函数依赖图 GG
  3. 从该图中找出关键属性 XX (可为空).
  4. 查看 GG 中有无独立回路, 若没有, 则输出 XX 即 RR 的唯一候选键, 转至步骤 6, 否则转至步骤 5
  5. 从各个独立回路中各取一个结点对应属性, 并与 XX 组合成一个候选键, 然后重复这一过程, 直到取尽所有可能的组合为止, 此时结果即 RR 全部候选键.

举例:
设 R(O,B,L,S,Q,D)R(O,B,L,S,Q,D), 其函数依赖集 F={S→D,D→S,I→B,B→I,B→O,O→B}F=\{S\to D,D\to S,I\to B,B\to I,B\to O,O\to B\}, 求 RR 的所有候选键
解:

  1. Fm={S→D,D→S,I→B,B→I,B→O,O→B}F_m=\{S\to D,D\to S,I\to B,B\to I,B\to O,O\to B\}
  2. 构造函数依赖图
  3. 关键属性集: Q{Q}
  4. 共有 4 条回路, 但回路 IBIIBI 和 BOBBOB 不是独立回路, 而 SDSSDS 和 IBOBIIBOBI 是独立回路. 共有 2×3=62\times 3=6 个候选键. 每个候选键都有 1+2=31+2=3 个属性, 所以所有候选键为: QSIQSI, QSBQSB, QSOQSO, QDIQDI, QDBQDB, QDOQDO

多属性依赖集求解解法

具体步骤如下:

  1. 将 RR 的所有属性分类: L类, R类, N类, LR类.
    令 XX 代表 L 类和 N 类, YY 代表 LR 类
  2. 求 X+X^+, 若 X+X^+ 包含 RR 的全部属性, 则 XX 为 RR 的唯一候选键, 转至步骤5, 否则转至步骤3
  3. 在 YY 中取一属性 AA, 求 (XA)+(XA)^+, 若 AA 包含 RR 的全部属性, 则 AA 为 RR 的候选键
    更换属性并反复进行这一过程, 直到试完 YY 中所有属性为止
  4. 如果已找出所有候选键, 则转至步骤5, 否则依次取两个, 三个, 等等, 求它们的属性闭包, 直到闭包包含R钓全部属性为止
  5. 停止求解输出结果

举例:
有关系模式 R(A,B,C,D,E)R(A,B,C,D,E), 其函数依赖集 F={A→BC,CD→E,B→D,E→A}F=\{A\to BC,CD\to E,B\to D,E\to A\}, 求 RR 的所有候选键
解:

  1. X 类属性为 ∅\varnothing, Y 类属性为 A,B,C,D,EA,B,C,D,E
  2. A+=ABCDEA^+=ABCDE, B+=BDB^+=BD, C+=CC^+=C, D+=DD^+=D, E+=ABCDEE^+=ABCDE, 所以 AA, EE 为 RR 的其中两个候选键
  3. 由于 BB, CC, DD 属性还未出现在候选键中, 于是将其两两组合后与 X 类属性组合以求闭包:
    (BC)+=ABCDE,(BD)+=BD,(CD)+=ABCDE(BC)^+=ABCDE, (BD)^+=BD, (CD)^+=ABCDE
    因此 BCBC, CDCD 为两个候选键
  4. 所有 Y 类属性均已经出现在候选键中, 所以所有候选键为 AA, EE, BCBC, CDCD
  • 标题: 数据库-函数依赖
  • 作者: Lucas
  • 创建于 : 2026-09-14 10:34:46
  • 更新于 : 2026-09-25 13:25:33
  • 链接: https://darkflamemasterdev.github.io/2026/09/14/数据库-函数依赖/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论