阅读指南
前言
最近学习数据库理论,刚好学到第六章的关于关系数据库极小函数依赖集的问题,此篇博客仅为记录学习,巩固知识点。在本篇中,会介绍什么是闭包,什么是极小函数依赖集以及极小函数依赖集的求法。如有问题,欢迎各位大佬指出——
闭包
在谈怎么样求最小函数依赖集之前,我们先来了解一下闭包的相关概念(主要是数据库这块涉及到的)。
在这里我们介绍两种,一种是函数依赖集 F F F的闭包,一种是属性集 X X X( X ⊆ U X⊆U X⊆U)关于 U U U上的函数依赖集F的闭包 X F + X_F{^+} XF+ 。
函数依赖集F的闭包
在关系模式 R < U , F > R<U,F> R<U,F>中为 F F F所逻辑蕴含的函数依赖的全体叫作 F F F的闭包,记为 F + F{^+} F+。
属性集关于函数依赖集的闭包
设 F F F为属性集 U U U上的一组函数依赖, X X X、 Y ⊆ U Y⊆U Y⊆U, X F + X_F{^+} XF+ = { A ∣ X → A A|X →A A∣X→A能由 F F F根据Armstrong公理导出}, X F + X_F{^+} XF+ 称为属性集 X X X关于函数依赖集 F F F的闭包。
说白了,这个闭包就是由一个(或一些)属性直接或间接推导出的所有属性的集合。
极小函数依赖集(最小覆盖)
定义
如果函数依赖集 F F F满足下列条件,则称 F F F是一个极小函数依赖集,亦称为最小依赖集或最小覆盖。
- F F F中任意函数依赖的右部仅含有一个属性。
- F F F中不存在这样的函数依赖 X → A X →A X→A,使得 F F F与 F F F−{ X → A X →A X→A}等价。
- F F F中不存在这样的函数依赖 X → A X →A X→A, X X X有真子集 Z Z Z使得 F F F−{ X → A X →A X→A} ∪ \cup ∪{ Z → A Z→A Z→A}与 F F F等价。
解释
根据定义,我们知道,最小依赖集必须满足下面三个条件:
- 被决定因素最小化: F F F的最小函数依赖的右侧只能有一个属性。
- 决定因素最小化: F F F中不允许有这样的函数依赖:若函数依赖集中存在 A B → Y AB\rightarrow Y AB→Y,现对该依赖的左部进行化简,即删除 A A A,得 B → Y B\rightarrow Y B→Y;或删除 B B B,得 A → Y A\rightarrow Y A→Y。在经过化简后的函数依赖集与没有化简前的函数依赖集等价,这样的函数依赖是不允许存在 F F F中的。
- 函数依赖数目最小化: 现存的函数依赖集中去掉一个函数依赖 X → A X →A X→A,所得到的新的函数依赖集与原来的函数依赖集是等价的,这样的函数依赖是不允许存在 F F F中的。
应当指出, F F F的最小依赖集 F m F_m Fm不一定唯一,它与对各函数依赖 F D i FD_i FDi及 X → A X →A X→A中 X X X各属性的处置顺序有关。
通用算法
先插入一个推理规则:(由Armstrong公理系统的三条推理规则而得到的一个推理规则。)
分解规则: 由 X → Y X\rightarrow Y X→Y以及 Z ⊆ Y Z⊆Y Z⊆Y,可以得到 X → Z X\rightarrow Z X→Z。
分三步对 F F F进行 “ “ “极小化处理 ” ” ”,找出 F F F的一个最小依赖集来。
步骤:
Step1
逐一检查 F F F中各函数依赖 F D i FD_i FDi,例如对于函数依赖: X → A B X\to AB X→AB,使用分解规则,将其替换为{ X → A X\to A X→A, X → B X\to B X→B}。
Step2
逐一取出 F F F中左部非单个属性的依赖 F D i FD_i FDi,判断左部的多余属性是否可以去掉。例如对于函数依赖 A B → C AB\to C AB→C,判断 A A A是否多余,则去掉 A A A,考查 B B B的闭包,如果其包含 C C C,则 A A A为多余属性,此时用 B → C B\to C B→C取代 A B → C AB\to C AB→C,否则不能取代。或者判断 B B B是否多余,则去掉 B B B,考查 A A A的闭包,如果其包含 C C C,则用 A → C A\to C A→C取代 A B → C AB\to C AB→C,否则不能取代。以此重复,直到左边的决定因素都达到最小化,或者不能取代,则结束。
Step3
逐一检查 F F F中各函数依赖 F D i FD_i FDi:例如对于函数依赖 X → A X\to A X→A,令 G = F − G=F- G=F− { X → A X\to A X→A},去掉 X → A X\to A X→A,求属性集 X X X关于函数依赖集 G G G的闭包,如果其包含 A A A,说明这个函数依赖是多余的,那么我们就可以删除这个函数依赖。
最后剩下的 F F F就一定是极小依赖集,并且与原来的 F F F等价。因为对 F F F的每一次 “ “ “改造 ” ” ”,都保证了改造前后的两个函数依赖集等价。
举例
R = R= R={ A , B , C , D , E , G A,B,C,D,E,G A,B,C,D,E,G}, F = F= F={ B → D B\to D B→D, D G → C DG\to C DG→C, B D → E BD\to E BD→E, A G → B AG\to B AG→B, A D G → B C ADG\to BC ADG→BC},求 F F F的最小函数依赖。
解
(这里解得顺序和上面步骤不太一样,在不影响最终结果时,其实可以换一下顺序的,不过还是建议大家按上面的步骤来,不然有时候可能会造成去掉的函数依赖数目变少了。不过本例中,顺序交换没有影响,主要是在第三步计算左部因子会比较快一些~,因此决定调一下顺序。)
1.首先根据函数依赖的分解性,对F进行第一次筛选。
需要变动的有: A D G → B C ADG\to BC ADG→BC 拆解成 A D G → B ADG\to B ADG→B, A D G → C ADG\to C ADG→C
得新的函数依赖集: F = F= F={ B → D B\to D B→D , , , D G → C DG\to C DG→C , , , B D → E BD\to E BD→E , , , A G → B AG\to B AG→B , , , A D G → B ADG\to B ADG→B , , , A D G → C ADG\to C ADG→C}
2.然后筛选多余的函数依赖。
- 去除 B → D B\to D B→D得 F = F= F={ D G → C DG\to C DG→C , , , B D → E BD\to E BD→E , , , A G → B AG\to B AG→B , , , A D G → B ADG\to B ADG→B , , , A D G → C ADG\to C ADG→C},求得 B F + = B_F{^+}= BF+={ B B B},不包含 D D D,故不能去掉。
- 去掉 D G → C DG\to C DG→C,得 F = F= F={ B → D B\to D B→D , B D → E ,BD\to E ,BD→E , , , A G → B AG\to B AG→B , , , A D G → B ADG\to B ADG→B , , , A D G → C ADG\to C ADG→C},求得 D G F + = DG_F{^+}= DGF+={ D , G D,G D,G},不包含 C C C,故不能去掉。
- 去掉 B D → E BD\to E BD→E,得 F = F= F={ B → D B\to D B→D , D G → C ,DG\to C ,DG→C , , , A G → B AG\to B AG→B , , , A D G → B ADG\to B ADG→B , , , A D G → C ADG\to C ADG→C},求得 B D F + = BD_F{^+}= BDF+={ B , D B,D B,D},不包含 E E E,故不能去掉。
- 去除 A G → B AG\to B AG→B得 F = F= F={ B → D B\to D B→D , , , D G → C DG\to C DG→C , , , B D → E BD\to E BD→E , , , A D G → B ADG\to B ADG→B , , , A D G → C ADG\to C ADG→C},求得 A G F + = AG_F{^+}= AGF+={ A , G A,G A,G},不包含 B B B,故不能去掉。
- 去除 A D G → B ADG\to B ADG→B得 F = F= F={ B → D B\to D B→D , , , D G → C DG\to C DG→C , , , B D → E BD\to E BD→E , , , A G → B AG\to B AG→B , , , A D G → C ADG\to C ADG→C},求得 A D G F + = ADG_F{^+}= ADGF+={ A , B , C , D , E , G A,B,C,D,E,G A,B,C,D,E,G},包含 B B B,故去掉函数依赖 A D G → B ADG\to B ADG→B。
- 去除 A D G → C ADG\to C ADG→C得 F = F= F={ B → D B\to D B→D , , , D G → C DG\to C DG→C , , , B D → E BD\to E BD→E , , , A G → B AG\to B AG→B , , , A D G → B ADG\to B ADG→B},求得 A D G F + = ADG_F{^+}= ADGF+={ A , B , C , D , E , G A,B,C,D,E,G A,B,C,D,E,G},包含 C C C,故去掉函数依赖 A D G → C ADG\to C ADG→C。
经过第二次筛选,得到新的函数依赖集: F = F= F={ B → D B\to D B→D , , , D G → C DG\to C DG→C , , , B D → E BD\to E BD→E , , , A G → B AG\to B AG→B}
3.决定因素最小化,将函数依赖的左部尽可能的化简。
- 对于 D G → C DG\to C DG→C,将 D D D去掉,得 G → C G\to C G→C, G F + = G_F{^+}= GF+={ G G G},不包含 C C C,故不能去掉。将 G G G去掉,得 D → C D\to C D→C, D F + = D_F{^+}= DF+={ D D D},不包含 C C C,故不能去掉。故函数依赖 D G → C DG\to C DG→C已是最简,不能再化简了。
- 对于 B D → E BD\to E BD→E,将 B B B去掉,得 D → E D\to E D→E, D F + = D_F{^+}= DF+={ D D D},不包含 E E E,故不能去掉。将 D D D去掉,得 B → E B\to E B→E, B F + = B_F{^+}= BF+={ B , D , E B,D,E B,D,E},不包含 E E E,故可以去掉 D D D。故函数依赖 B D → E BD\to E BD→E换为 B → E B\to E B→E。
- 对于 A G → B AG\to B AG→B,将 A A A去掉,得 G → B G\to B G→B, G F + = G_F{^+}= GF+={ G G G},不包含 B B B,故不能去掉。将 G G G去掉,得 A → B A\to B A→B, A F + = A_F{^+}= AF+={ A A A},不包含 B B B,故不能去掉。故函数依赖 A G → B AG\to B AG→B已是最简,不能再化简了。
综上,最小函数依赖集为 F = F= F={ B → D B\to D B→D , , , D G → C DG\to C DG→C , , , B → E B\to E B→E , , , A G → B AG\to B AG→B}。
此外,在第二步中,我们筛选函数依赖时,是“串行”的——也就是一边看一边去掉(如果可以去掉的话)。我们上面已经指出过最小函数依赖集不唯一,那么根据处理的顺序,也就是去的是顺序,会使得我们最终得到的最小函数依赖集可能不同。 下面我们给出一个简单的例子:
在这里我们省去具体的步骤,仅直接给出结果(其实很简单,大家可以自己推一下)。我们处理的顺序按照上面解法里面的Step1-Step3。我们看到最终结果有两个最小依赖集,其原因就在我们处理的顺序不同,你去掉这个的时候,另一个可能就不是冗余的了。
结语
本文定义以及例子参考自:
- 《数据库系统概论(第五版)》 王珊 萨师煊 编著 清华大学出版社
- csdn博文 关系数据库理论之最小函数依赖集
- 学校老师上课给的题目