在数据库设计中范式分解是我们经常会用到的一种优化方法,这部分的概念还是非常的多的,接下来我会首先介绍范式分解的相关概念,然后具体介绍范式分解的方法。相信静下心来读完这边文章对你应该会有点帮助,如果你准备好了,那么就让我们开始吧~
如果A->B,称为A决定B,即当A确定时,B的值唯一
求闭包的过程很简单,比如求A的闭包(A+),只需找到所有只有A在左边的函数依赖,将所有的右边的都加到A的闭包中来,遍历所有的函数依赖,最后不要忘记加上A自己
闭包可以用来求关系模式的key:对于R(A,B,C),若A+ = ABC , 那么可以判定A是R的key。
称A->A这样的函数依赖为一个平凡的依赖,当然由此我们也知道了非平凡依赖是什么了。
所有的候选键包含的属性集合是主属性集合
相应的非主属性是所有候选码都不包含的属性
每个属性都具有原子性,是不可再被细分的
定义:如果关系模式R是第一范式的,而且关系中每一个非主属性不部分依赖于主键,称R是第二范式的。
所以第二范式的主要任务就是
满足第一范式的前提下,消除部分函数依赖。
什么叫部分依赖呢,比如AB是R(A,B,C)的主键,那么如果有A->C,这就是一个部分函数依赖
在第二范式的基础上,不存在非主属性对码的传递性依赖
举个例子: R(A,B,C),A是主键,如果同时有A->B和B->C,这就是一个传递依赖了
对于所有的非平凡依赖,它的左边必须是一个超码
即在第三范式的基础上,消除了对主属性对码的部分和传递依赖
和BC范式非常相像,对于所有的非平凡多值依赖,左边必须是超码
&无关项(extraneous attribute)定义:若果去除函数依赖中的属性不会改变函数依赖的闭包,就称该属性是无关的。
形式定义:
●如果A∈α并且F逻辑蕴涵(F-{α→β})U{(α-A)→β},则A在α是无关的
●如果A∈β并且函数依赖{F-{α→β})U{α→(β-A)}逻辑蕴涵F,则A在β是无关的(下面有例题)
检验方法:
令R为一关系模式,F是在R上成立的给定的函数依赖集。考虑依赖α→β上的属性A。
●如果A∈α,令λ=α-{A},并且计算λ→β是否可以由F推出。
●如果A∈β,F’=(F-{α→β})U{α→(β-A)},并检验α→A是否能够由F’推出。
&正则覆盖定义:F的正则覆盖Fc是一个依赖集,使得F与Fc相互逻辑蕴涵。此外,还包含如下性质:
●Fc中任何函数依赖都不含无关属性。
●Fc中函数依赖左半部分都是唯一的。即,Fc中不存在α1→β1,α2→β2,满足α1=α2。
例子:R(A,B,C)
F={A->BC, B->C, A->B, AB->C}
F={A->BC, B->C, AB->C}
F={A->BC, B->C}
F={A->B, B->C}
那么了解正则覆盖有什么作用呢?
可证明Fc与F具有相同的闭包,即验证是否满足Fc等价于验证是否满足F,这一点我们一会儿验证范式分解是否正确会用到。
参考链接
如果我们把R分解为R1和R2,此分解是无损的必须满足:α=R1∩R2是R1或者是R2的超码。
需要验证 {F1 并 F2 并 F3。。。} += F+,即每一个分解出的R包含的函数依赖的并集的闭包和原集F的闭集相等。
如果F上的每一个函数依赖都在其分解后的某一个关系上成立,则这个分解是保持依赖的(注意这是一个充分条件!)。如果上一点不成立,并不能断言分解不是保持依赖的,还要使用下面的通用方法来做进一步判断。
对F的每一个A->B 使用以下流程
这里的属性闭包是在函数依赖集F下计算出来的。如果result中包含了β的所有属性,则函数依赖α→β。分解是保持依赖的当且仅当上述过程中F的所有依赖都被保持。
当然这个是非常麻烦的,因为要验证所有的函数依赖。所以待会我们会介绍运用正则覆盖简化函数依赖集,减少工作量。
好了,以上部分是我们要用到的所有相关概念,如果有的概念不是很清楚,建议你看看别的博主的文章,这方面的资料还是很多的。
以下是范式分解的流程:
这样分解后得到的就满足BC范式了
在分解完之后很重要的一点是要对无损性和依赖保持进行检查,如果不能满足,那么宁愿退化成第三范式。