范式分解

在数据库设计中范式分解是我们经常会用到的一种优化方法,这部分的概念还是非常的多的,接下来我会首先介绍范式分解的相关概念,然后具体介绍范式分解的方法。相信静下心来读完这边文章对你应该会有点帮助,如果你准备好了,那么就让我们开始吧~

    • 第一部分 相关概念
      • 函数依赖FD
      • 闭包Closure
      • 平凡依赖trivial FD
      • 主属性
      • 范式Normal Form
        • 第一范式
        • 第二范式
        • 第三范式
        • BC范式
        • 第四范式
      • 正则覆盖
      • 无损连接lossless join
      • 依赖保持dependency preserving
    • 第二部分 范式分解

第一部分 相关概念

1. 函数依赖(FD)

如果A->B,称为A决定B,即当A确定时,B的值唯一

2. 闭包(Closure)

求闭包的过程很简单,比如求A的闭包(A+),只需找到所有只有A在左边的函数依赖,将所有的右边的都加到A的闭包中来,遍历所有的函数依赖,最后不要忘记加上A自己
闭包可以用来求关系模式的key:对于R(A,B,C),若A+ = ABC , 那么可以判定A是R的key。

3. 平凡依赖(trivial FD)

称A->A这样的函数依赖为一个平凡的依赖,当然由此我们也知道了非平凡依赖是什么了。

4. 主属性

所有的候选键包含的属性集合是主属性集合
相应的非主属性是所有候选码都不包含的属性

5. 范式(Normal Form)

1.第一范式

每个属性都具有原子性,是不可再被细分的

2.第二范式

定义:如果关系模式R是第一范式的,而且关系中每一个非主属性不部分依赖于主键,称R是第二范式的。
所以第二范式的主要任务就是
满足第一范式的前提下,消除部分函数依赖。
什么叫部分依赖呢,比如AB是R(A,B,C)的主键,那么如果有A->C,这就是一个部分函数依赖

3.第三范式

在第二范式的基础上,不存在非主属性对码的传递性依赖
举个例子: R(A,B,C),A是主键,如果同时有A->B和B->C,这就是一个传递依赖了

4.BC范式

对于所有的非平凡依赖,它的左边必须是一个超码
即在第三范式的基础上,消除了对主属性对码的部分和传递依赖

5.第四范式

和BC范式非常相像,对于所有的非平凡多值依赖,左边必须是超码

6. 正则覆盖

&无关项(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,这一点我们一会儿验证范式分解是否正确会用到。

参考链接

7. 无损连接(lossless join)

如果我们把R分解为R1和R2,此分解是无损的必须满足:α=R1∩R2是R1或者是R2的超码。

8. 依赖保持(dependency preserving)

需要验证 {F1 并 F2 并 F3。。。} += F+,即每一个分解出的R包含的函数依赖的并集的闭包和原集F的闭集相等。
如果F上的每一个函数依赖都在其分解后的某一个关系上成立,则这个分解是保持依赖的(注意这是一个充分条件!)。如果上一点不成立,并不能断言分解不是保持依赖的,还要使用下面的通用方法来做进一步判断。
对F的每一个A->B 使用以下流程

Created with Raphaël 2.1.0 result = A for each 分解后的R t=(result∩Ri)+ ∩Ri result=result∪t result没有产生变化? 结束 yes no

这里的属性闭包是在函数依赖集F下计算出来的。如果result中包含了β的所有属性,则函数依赖α→β。分解是保持依赖的当且仅当上述过程中F的所有依赖都被保持。

当然这个是非常麻烦的,因为要验证所有的函数依赖。所以待会我们会介绍运用正则覆盖简化函数依赖集,减少工作量。

第二部分 范式分解

好了,以上部分是我们要用到的所有相关概念,如果有的概念不是很清楚,建议你看看别的博主的文章,这方面的资料还是很多的。

以下是范式分解的流程:

Created with Raphaël 2.1.0 利用闭包原理求出R的所有候选键 找出一个违反要求的函数依赖A->B 求A的闭包A+ 将R分解为R1{A+}和R2{(R-A+) U A+} 均满足范式要求? 结束 yes no

这样分解后得到的就满足BC范式了
在分解完之后很重要的一点是要对无损性和依赖保持进行检查,如果不能满足,那么宁愿退化成第三范式。

你可能感兴趣的:(database)