算法:
1.求出R上的函数依赖集F的最小函数依赖集Fm
2.如果R中某些属性在Fm中的每个函数依赖的左右两边都不出现,那么就将这些属性从R中分离出去,单独构成一个分解的字模式放入P中。
3.如果Fm中有多个左部相同属性的函数依赖,可依据合并率将它们的右部分合并起来。
4.对于Fm中的每一个函数依赖:X—>A,构成一个分解的子模式{X,A}放P中。
5.检查在分解后的子模式集合中是否包含有R的一个候选码,如果没有包含,则把候选码作为一个分解放入P中(如果有多个候选码,任选1个)
6.结束。
注:前置知识点:最小函数依赖集、候选键的计算。
例题:R(A,B, C,D,E,G),F = {A -> B , A -> C , A - >D , A -> E , A - >G , CDE ->G , G ->C , G -> D}
解:
步骤一:计算最小函数依赖集Fm 。
假设删除A -> B,则A的闭包={A,C,D,E,G},无B,保留
假设删除 A -> C,则A的闭包={A,B,D,E,G,C},有C,删除,
此时F更新为:
F = {A -> B , A - >D , A -> E , A - >G , CDE ->G , G ->C , G -> D}
假设删除A - >D,则A的闭包={A,B,E,G,C,D},有D,删除
此时F更新为:
F = {A -> B , A -> E , A - >G , CDE ->G , G ->C , G -> D}
假设删除A - >E,则A的闭包={A,B,G,C,D},无E,保留
假设删除A - >G,则A的闭包={A,B,E},无G,保留
假设删除CDE - >G,则CDE的闭包={C,D,E},无G,保留
假设删除G - >C,则G的闭包={G,D},无C,保留
假设删除G - >D,则G的闭包={G,C},无D,保留
看冗余项,
如果删除C,则DE的闭包={D,E},保留
如果删除D,则CE的闭包={C,E},保留
如果删除E,则CD的闭包={C,D},保留
此时,最小函数依赖集Fm为:
Fm = {A -> B , A -> E , A - >G , CDE ->G , G ->C , G -> D}
*注:Fm不唯一
步骤二:R中的所有属性均出现
步骤三:合并Fm
Fm= {A->BEG , CDE ->G , G ->CD }
步骤四:
P={R1(ABEG),R2(CDEG),R3(CDG)}
计算求得F的候选键为A,显然R1中包含了A,故步骤五结束。
注意:此时观察到 P中存在冗余模式,即 R3是R2的子集,因此将其合并
更新P={R1(ABEG),R2(CDEG)}
综上,P为一个保持无损连接和函数依赖的3NF