前言

定义1:设R(U,F)是一个关系模式,F是函数依赖集,若F + ^+ += ( U U U i = 1 k F i ) _{i=1}^{k}F_i) i=1kFi) + ^+ +,则R<U, F>的分解ρ={ R1<U1, F1>,R2<U2, F2>,…,Rk<Uk, Fk> } ,则分解ρ保持函数依赖。
定义2:分解前函数依赖的闭包和分解后各个函数依赖并集的闭包相等;即分解不能丢失函数依赖
保持函数依赖性判断完全可以根据定义及Armstrong公理进行判断。对于不能简单的推算出是否保持函数依赖,则需要通过以下算法实现。

判断算法

判断一个模式分解是否保持函数依赖,假设R(U,F)分解为R1(U1,F1)、R2(U2,F2)… R n _n n(U n _n n,F n _n n
其中:U 1 _1 1 ∪ ∪ U 2 _2 2 ∪ ∪ U n _n n=U,F 1 _1 1、F 2 _2 2、F n _n n分别是F在U 1 _1 1、U 2 _2 2…U n _n n上的投影。处理步骤如:
第一步:设F’=F 1 _1 1UF 2 _2 2…UF n _n n;判断F’是否覆盖了F,若包含了F中所有的函数依赖,则一定是保持函数依赖的,判断结束,否则进入第二步
第二步:对F’中没显式包含的函数依赖依据armstrong公理做初步判断,F’蕴含了该函数依赖,F’覆盖了该函数依赖。如不能判断得出,使用以下算法去实现,只要有一个函数依赖没有覆盖的到,则不保持函数依赖。是否蕴含了某个函数依赖判断的算法如下:

假设:需要判断是否蕴含了 α α α-> β β β函数依赖;
令 Result= α α α
开始扫描R i _i i,T=(Result ∩ R ∩R R i _i i) F + _F^+ F+∩Ri
令:Result=Result ∪ ∪ T
Result包含了 β β β,则: α α α-> β β β成立,算法终止
Result有变化,但还没包含 β β β,继续下一轮
Result无变化,且不包含 β β β,则: α α α-> β β β不成立,分解不覆盖 α α α-> β β β,说明不保持函数依赖

示例

例1:已知R<U,F>,U={A,B,C,D,E},F={A—>C,B—>C,C—>D,DE—>C,CE—>A},
R的一个分解为R1(AD),R2(AB),R3(BE),R4(CDE),R5(AE),判断这个分解是否具有函数依赖性。
解:
求投影:R 1 _1 1 F 1 _1 1{A—>D} ,R 2 _2 2 F 2 _2 2{ Ø Ø Ø} ,R 3 _3 3 F 3 _3 3{ Ø Ø Ø},R 4 _4 4(CDE), F 4 _4 4(DE->C,C->D}
F’=F − - (F 1 _1 1UF 2 _2 2UF 3 _3 3UF 4 _4 4)={A->D、DE->C,C->D}
A->C、B->C、CE->A这些函数依赖需要进一步的判断是否被覆盖到

根据Armstrong公理简单判断不出,F’是否蕴含了A->C、B->C、CE->A等函数依赖

转入求闭包操作:
A->C:
第一轮
令: Result={A}
Result与R1求交,为{A}, 求A的闭包:A F + _F^+ F+={ACD}, 则T={ACD} ∩ ∩ R 1 _1 1={AD}; Result= Result ∪ ∪ T={AD}
Result与R2求交,为{A}, 求A的闭包:A F + _F^+ F+={ACD}, 则T={ACD} ∩ ∩ R 2 _2 2={A}; Result= Result ∪ ∪ T={AD}
Result与R3求交,为{ Ø Ø Ø}, Result= Result ∪ ∪ T={AD}
Result与R4求交,为{D}, 求D的闭包:D F + _F^+ F+={D}, 则T={D} ∩ ∩ R 4 _4 4={D} Result= Result ∪ ∪ T={AD}
Result与R5求交,为{A}, 求A的闭包:A F + _F^+ F+={ACD}, 则T={ACD} ∩ ∩ R 5 _5 5={A} Result= Result ∪ ∪ T={AD}
第一轮,开始Result={A},最后得到Result={AD},Result发生变化,开始第二轮
第二轮
此时, Result={AD}
Result与R1求交,为{AD}, 求AD的闭包:AD F + _F^+ F+={ACD}, 则T={ACD} ∩ ∩ R 1 _1 1={AD}; Result= Result ∪ ∪ T={AD}
Result与R2求交,为{A}, 求A的闭包:A F + _F^+ F+={ACD}, 则T={ACD} ∩ ∩ R 2 _2 2={A}; Result= Result ∪ ∪ T={AD}
Result与R3求交,为{ Ø Ø Ø}, Result= Result ∪ ∪ T={AD}
Result与R4求交,为{D}, 求D的闭包:D F + _F^+ F+={D}, 则T={D} ∩ ∩ R 4 _4 4={D} Result= Result ∪ ∪ T={AD}
Result与R5求交,为{A}, 求A的闭包:A F + _F^+ F+={ACD}, 则T={ACD} ∩ ∩ R 5 _5 5={A} Result= Result ∪ ∪ T={AD}
第二轮,开始Result={AD},最后得到Result={AD},Result无变化且Result不包含C,不能覆盖A->C,无需做其他两个验证了。
所以:此模式分解不保持函数依赖性。

例2:给定关系模式R(U,F),U={A,B,C,D} F={A->B, B->C, C->D, D->A}
分解为R1:{AB}、R2{BC}、R3{CD},判断此分解是否具有依赖保持性
解:求投影
R 1 _1 1 F 1 _1 1{A->B,B->A} ,
R 2 _2 2 F 2 _2 2{C->B,B->C} ,
R 3 _3 3 F 3 _3 3{C->D,D->C},
F’=(F 1 _1 1UF 2 _2 2UF 3 _3 3UF 4 _4 4)={A->B,B->A,C->B,B->C,C->D,D->C}
缺少: 函数依赖D->A;
D F ′ + _F'^+ F+={DCBA};表示F’蕴含了D->A,F’与F是等价的;所以保持函数依赖性
完毕。

我们可以使用第三步方法再验证一下F’是否蕴含了D->A
第一轮
令: Result={D}
Result与R1求交,为{ Ø Ø Ø}, 求 Ø Ø Ø的闭包得到 Ø Ø Ø,T={ Ø Ø Ø} ∩ ∩ R 1 _1 1={ Ø Ø Ø}; Result= Result ∪ ∪ T={D}
Result与R2求交,为{ Ø Ø Ø}, 求 Ø Ø Ø的闭包得到 Ø Ø Ø,T={ Ø Ø Ø} ∩ ∩ R 2 _2 2={ Ø Ø Ø}; Result = Result ∪ ∪ T={D}
Result与R3求交,为{D}, 求D的闭包,D F + _F^+ F+={ABCD},T={ABCD} ∩ ∩ R 3 _3 3={CD}; Result= Result ∪ ∪ T={CD}
由于最后的Result={CD}和最初的Result={D}不同,我们开始第二轮
第二轮
Result={CD}
Result与R1(AB)求交,为{ Ø Ø Ø}, 求 Ø Ø Ø的闭包得到 Ø Ø Ø,T={ Ø Ø Ø} ∩ ∩ R 1 _1 1={ Ø Ø Ø}; Result= Result ∪ ∪ T={CD}
Result与R2(BC)求交,为{C}, 求C的闭包C F + _F^+ F+={ABCD},T={ABCD} ∩ ∩ R 2 _2 2={BC}; Result= Result ∪ ∪ T={BCD}
Result与R3(CD)求交,为{CD}, 求CD的闭包,DC F + _F^+ F+={ABCD},T={ABCD} ∩ ∩ R 3 _3 3={CD}; Result= Result ∪ ∪ T={BCD}
由于最后的Result={BCD}和最初的Result={CD}不同,我们开始第三轮
第三轮
Result={BCD}
Result与R1(AB)求交,为{B}, 求B的闭包B F + _F^+ F+={ABCD},T={ABCD} ∩ ∩ R 1 _1 1={AB}; Result= Result ∪ ∪ T={ABCD}
此时:result已经包含了A,说明F’是否蕴含了D->A
F’与F等价,保持函数依赖性。

结论

保持函数依赖性,就是做模式分解后的F’(各个子模式函数依赖的并集)是否与F(原有的函数依赖集)等价,F’包含所有的F中的函数依赖则可以得出保持函数的依赖性(充分条件),如果F’不显式包含F中的函数依赖,还需进一步判断,判断方法有两条,第一种是通过F’中的属性闭包去求,是否蕴含函数依赖(这种方法要求做函数投影时,不能缺项);第二种使用给定的算法去求,对投影要求简单,但过程特别麻烦。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐