话说这本书也是够奇怪的,前面义正词严的讲了一个decomposition method of BCNF然后后面又说这个方法并不充分……嘛,开讲。
根据笔记10的内容,再拆分一个非BCNF的数据表的时候,我们有说过,发现函数依赖LA(a)->LA(b)不符合BCNF的时候,正确的做法是将LA(a),LA(b)拆开做一个表,然后R-LA(a)+LA(b)再做一个表。
但是新出来的表能满足bcnf么?未必,但是它至少接近了一点:
让我们来看以下例子:
有R(A,B,C,D,E),有F:A->B,BC->D.,
那么很明确,A->B是不符合BCNF的定义(事实上这个说法也是存在问题的,待会再说
那么就拆分,成为:R1(A,B) R2(ACDE),然后我们发现,BC于R2没有关系了,按照以前的说法,这就拆分完成了。
但是并没有。
由F可推出AC->D,所以R2仍然不是一个BCNF的关系。
问题出在哪里呢?问题在于,每一次拆分表,表内带有的Fnew应为F+ 内带有拆封出来的部分,这样才是真正的概念上的拆分,而这个时候,我们又不得不回到BCNF概念上的问题:
BCNF的概念是什么?
对于每一个存在于F+中的函数依赖,其必须满足以下两个条件中的一个:
1.这个函数依赖是自导的(不重要的 trivial)
2.对于依赖LA(a)->LA(b),LA(a)为该关系的一个超键。
那尴尬的事情就发生了,因为根据书上的例子,我可以提出一个R(A,B,C,D,E),A->B,B->CDE.
我们可以推得,A为该关系的一个超键,但是这个超键是由F+给予的,而并非由函数直接给出的
(或者求得A+
所以,对于任何一个拆分,因为涉及到超键的概念,而不计算F+或者A就无法获得其超键,所以一个替换的判别算法为:
计算出F+
易得任何拆分所得schema的函数依赖都基于F+,故对于F+中所存在的函数依赖左端,求得其在函数依赖的最大右端,然后判断其是否已经被拆分(被拆分即不成立)若没有拆分,则拆分处理,若已拆分,则不处理。
或者可以直接求得属性全排列,然后对每个排列求其闭包,若求得闭包,且闭包不为(R-闭包来源属性集),则这个依赖存在且不满足BCNF,拆分之,过程几乎和上一个一样。
3nf的分法
求得Fc
对于Fc中每一个函数LA(a)->LA(b)创建一个表LA(a)LA(b)
对于任何的候选键,如果上述创建的表里没有一个包含它们,则创建一个新的表,属性是该候选键
对于任意一个上述的表的二元组a,b,若a是b的子集,则删去a,若b是a的子集,则删去b,直到没有东西可以删为止。
返回结果。