-
1 范式
-
2 规范化方法
-
3 分解效果
-
4 无损分解
-
5 保持函数依赖的分解
-
6 模型优化及总结
在这一节,我们将会正式回答第2个问题,希望你还记得:
2. 如何判断一个关系模式的良好级别?
在数据库中,将关系模式的良好程度分为若干个等级,这就是“范式”的概念。
1. 范式
定义: 关系数据库中符合某一级别的关系模式的集合。所谓“第几范式”,是表示关系的某一种级别,关系模式R为第几范式就可以写成:R ∈ xNF
常见的范式有(从低到高):
1NF Ì 2NF Ì 3CNF Ì BCNF Ì 4NF Ì 5NF
关系模式符合的范式越高,说明关系模式的良好程度越高。但设计关系模式时并不总是需要达到最高范式。本课程只讲到第三范式(3NF),这也是最常用的范式。
2. 第1范式(1NF)
定义:设R是一个关系模式,R属于第一范式当且仅当R中每一个属性A的值域只包含原子项,即不可分割的数据项。
第1范式的要求非常简单,就是关系模式中的每一个属性都必须是不可拆分的、原子的。比如我们来看看下面的这个例子:

在上面这个关系中,大家可以观察到:属性“系”其实是由两个子属性构成:系名+系地址,属性“课程”也是由两个子属性构成:课程名+任课教师,所以这两个属性都不是原子的,都可以继续拆分。拆分以后的结果如下:

这个结果符合1NF吗?还是不符合!不难看出,有的“教师名”属性包含了多位教师,所以它依然不是原子的,我们应该进一步拆分,以确保每一个“教师名”属性只包含一位教师。如下所示:

好了!到这里,我们就把关系模式中的每一个属性变成了原子属性——不可拆分的属性。至此,这个非规范化(连1NF都不满足)的关系模式变成符合1NF了!
3. 第2范式(2NF)
定义:设R是一个关系模式,R属于第二范式当且仅当R是1NF,且每个非主属性都完全函数依赖于主码。
这个定义中提到了一个重要的概念:非主属性。回顾一下,还记得什么是非主属性吗?
候选码中的属性称作主属性,其它的称作非主属性。
2NF怎么理解呢?我们举个例子:
【例1】存在关系模式R(A,B,C,D),R满足函数依赖A→D;请判定R是否满足2NF?
解析:这里需要说明的是:属性AB有下划线标识,这意味着这两个属性是关系模式R中的主码。那又怎样呢?那就厉害了,主码是可以决定关系中的任何一个属性的!所以AB可以决定C或D!有同学会问这样一个问题吗:除了C和D以外,AB能不能决定A或者B呢?当然能,平凡的函数依赖吗!任何属性都可以决定自己或自己的子集,相信这不难理解。好了,我们把它表示出来:
AB→C ,AB→D
在理解了这一点以后,我们来分析一下R中的主属性和非主属性都有谁?根据前面的定义“候选码中的属性称作主属性,其它的称作非主属性。”,因为AB是主码,所以A、B是主属性,C、D是非主属性。
大家再看看题目!题目中还有一个条件:R满足函数依赖A→D!所以我们可以得出这样的结论:非主属性D部分函数依赖于主码。因此关系模式R不符合2NF!
继续:R不符合2NF,那我们如何改造R使其满足2NF呢?
考虑一下:R不符合2NF的原因是因为函数依赖A→D的存在。如果我们将这个函数依赖从R中去掉,那不就消除了这个部分函数依赖了吗?好的,如果你明白了这一点,那么现在的问题就变成了怎么去掉这个函数依赖呢?方法很简单,从关系R中去掉属性D,形成新关系R1(A,B,C)。
在R1(A,B,C)中存在函数依赖:AB→C,而且A或者B都不能独自决定C,所以非主属性C完全函数依赖于主码AB,因此R1满足2NF。现在有一个问题,被我们去掉的D怎么办?D是原始关系中存在的属性,是不能丢失的!因为如果D丢失,那么就意味着与D相关的数据的丢失!我们绝不能因为关系模式的规范化而丢失数据,所以我们可以尝试构建一个新关系R2(D)来存放与D相关的数据。那么现在原始的R就被我们变成了两个新的子关系模式:R1(A,B,C),R2(D)。
我们成功了吗?经过我们上面的讨论,R1已经满足2NF,而R2是一定满足2NF的!R2中只有一个属性D,因此无论如何都不可能有部分函数依赖的存在。所以似乎通过将R拆分为R1和R2,让我们达到了2NF的目标。事情真的是这样吗?其实我们遗漏了一件很重要的事情:那就是D和AB的关系!从现在的R1和R2是看不出任何D与AB 之间的关系的!没有关系!但是我们都知道题目中告诉了我们:A→D!所以怎么办?解决的办法就是将A同时放入R2,变成:R1(A,B,C),R2(A,D)。
好了!事情终于要告一段落了!在R2中,不存在部分函数依赖,R2属于2NF!并且我们找回了丢失的函数依赖:A→D,而且R2可以和R1通过关联字段A进行关联,以恢复出拆分之前的原始数据,即R=R1⋈ R2。这,就是我们想要的最终结果!
经过艰苦的分析、改进,我们最终将一个不满足2NF的关系模式通过拆分的方法转换成为了符合2NF的关系模式。这种拆分的方法在我们数据库中叫做“模式分解”。后面我们还会详细地讨论它!
4. 第3范式(3NF)
定义:设R是一个关系模式,R属于第三范式当且仅当R是2NF,且每个非主属性都非传递函数依赖于主
码。
3NF如何理解?关键点是不存在非主属性对主码的传递函数依赖,即满足第三范式的关系模式应该不存在如下依赖关系:
主属性 → 非主属性x → 非主属性y
首先需要强调的是:
满足2NF必须首先满足1NF,满足3NF必须首先满足2NF!
接下来我们要对最开始提出来的关系模式SLC进行病灶分析和手术治疗了!还记得这个异常多多的SLC吗!
SLC(Sno,Sname,Sdept,Loca,Cno,Grade)
同学们可以自己分析一下,SLC还是满足1NF的,所以现在我们需要分析的是它是否满足2NF?在开始把脉以前,先让我们弄清楚一些事情:
问题1:SLC的主属性和非主属性是谁?
前面曾经讨论过,SLC中的主码是(Sno,Cno),所以SLC中的主属性是:Sno和Cno,非主属性是:Sname、Sdept、Loca、Grade。
问题2:SLC中存在哪些函数依赖?
根据主码的特点,首先存在以下函数依赖:
(Sno,Cno)→Sname, (Sno,Cno)→Sdept, (Sno,Cno)→Loca, (Sno,Cno)→Grade
然后还存在下述函数依赖:
Sno→Sname,Sno→Sdept, Sno→Loca, Sdept→Loca
好了,分析SLC是否属于2NF的工作正式开始!2NF的定义是什么?不存在非主属性对主码的部分函数依赖。这里有吗?答案是肯定的。比如
(Sno,Cno)→Sname, Sno→Sname
(Sno,Cno)→Sdept, Sno→Sdept
(Sno,Cno)→Loca, Sno→Loca
不仅有!而且还很多!很尴尬!分析一下根源在哪里?你会发现根源其实出在Cno!如果没有Cno,一切的部分函数依赖瞬间消失!OK!怎么办?根据2NF中的讨论,最好的办法就是将Cno从SLC中移除,形成一个新关系SC(Cno)。但是需要我们注意的是:SLC中的Grade脱离了Cno和Sno是没有任何意义的!比如我给你一个90,不告诉你这是哪位同学的哪门课程的成绩,这有何意义呢?所以Grade应该从SLC移到SC。那么Sno是否也应该从SLC简单地移到SC呢?不能,因为在SLC 中Sno还决定着Sname等其它属性,所以Sno会被复制一份到SC。因此,我们得到了以下两个子关系模式:
SC(Sno,Cno,Grade) 其中(Sno,Cno)是主码。
SL(Sno,Sname,Sdept,Loca) 其中Sno是主码。
在SC中,Sno和Cno都不能独自决定Grade,所以非主属性Grade不存在对主属性(Sno,Cno)的部分函数依赖,因此SC属于2NF。在SL中,主属性只有Sno,所以无论如何都不可能存在非主属性对主属性的部分函数依赖(部分函数依赖的存在一定是主属性有多个),因此SL也属于2NF。
SC和SL都属于2NF,那么它们都属于3NF吗?3NF的条件是:每个非主属性都非传递函数依赖于主码。这意味着非主属性必须不低于2个,否则谈不上传递依赖,因此SC一定属于3NF。SL呢?这是我们讨论的焦点。先来看看SL中存在的函数依赖都有哪些:
Sno→Sname,Sno→Sdept, Sno→Loca, Sdept→Loca
看到了吗?Sno→Sdept, Sdept→Loca,所以非主属性Loca传递函数依赖于主属性Sno。可以下结论了:SL不属于3NF!怎么办?还用说?一个字:“拆”(模式分解)。大家可以根据前面的思路,自己尝试着分解一下。
最后的结果是我们将SL分解成为了以下两个子关系模式:
S(Sno,Sname,Sdept) 其中主码是Sno。
L(Sdept,Loca) 其中主码是Sdept。
这样分解的原因是由于要去除造成传递函数依赖存在的因素: Sdept→Loca。而为了不造成S和L联系的丢失,Sdept被作为关联字段分别放入了两个新的子关系模式中。最后来检视一下,S和L都满足3NF吗?
在S中,非主属性Sname和Sdept不能互相决定,所以不存在非主属性对主属性的传递函数依赖,因此S属于3NF;在L中,非主属性只有Loca一个,何谈传递性,因此L 属于3NF。
给出最终的结果,我们将SLC分解成为了以下子关系模式:
SC(Sno,Cno,Grade)
S(Sno,Sname,Sdept)
L(Sdept,Loca)
从而将仅仅满足1NF的SLC规范化到3NF。
这就是数据库规范化理论中的三级范式(1NF、2NF、3NF)。
------------------------------------------------------------------
最后,让我们正式地回答第2个问题:
2. 如何判断一个关系模式的良好级别?
一个关系模式符合的范式级别越高(3NF>2NF>1NF),说明这个关系模式越良好。




























