您的位置:首页 > 数据库

数据库"范式"

2016-07-05 16:55 225 查看

1.为什么要学习数据库”范式”?

当我们独立去完成一个自己的小项目的时候,肯定要去设计”合适”的数据模型即逻辑架构,那么,我们怎么知道自己设计的数据模型是最”合适”的呢?肯定得有一个标准去衡量自己设计的数据模型,看到这里,大家知道为什么要学习范式了.

2.”范式”能解决什么问题?

刚才说过,学习范式是为了去设计一个”合适的”数据模型,那么,一个”合适”的数据模型,它能解决什么问题呢?

1.消除数据冗余.

2.消除更新异常.

3.消除插入异常

4.消除删除异常.

3.范式的概念

范式是符合某一种级别的关系模式的集合,它是关系数据库理论的基础,也是我们在设计数据库结构中所要尊循的规则和指导方法. 数据库有5个基本的范式:即第一范式(1NF),第二范式(2NF),第三范式(3NF),BCNF(BC范式),第四范式(4NF)。甚至还有5NF,6NF,DK范式,本文只讨论前面五种范式,这五种范式,就是为了解决第二个点中所说的问题.从1NF到4NF逐级提高标准,大家可以把它理解为猿到人的进化过程。  

4.具体的例子

用一个具体的例子来分析这几种范式.  

学号姓名系名宿舍楼课程号成绩
03001周毅电信系A楼语文95
03001周毅电信系A楼数学89
04015崔勇计算机系C楼大物70
04015崔勇计算机系C楼英语85
03018王文涛电信系A楼语文87
03019马季军法律系B楼大物88
03019贺智平法律系B楼大物56
在上面提到了关系模式.而这张表的关系有

1.学号(x)–>姓名(y).

2.学号(x)–>系名(y).

3.系名(x)–>宿舍楼(y).

4.(学号,课程)(x)–>成绩(y).

怎样去理解上面的关系呢?它们的关系就是y=x^2,当x确定时,y一定有唯一值,即x唯一确定y.

4.几种特殊的函数依赖

1.平凡函数依赖:如果A属性组唯一确定B,并且B属性属于A属性组,那么A–>B是平凡函数依赖。eg:在上表中(学号,课程)—>课程.课程属于(学号,课程)这个属性组. 对于任以关系模式,平凡函数依赖都是成立的。所以,讨论它是,没有意义的,所以大家了解就行.

2.非平凡函数依赖:如果A属性组唯一确定B,并且B属性不属于A属性组,那么A—>B是非平凡函数依赖.eg:在上表中(学号,课程)—->成绩,成绩不属于(学号,课程)这个属性组,所以是非平凡函数依赖.

3.部分函数依赖:A属性组可以确定B,但是B不完全依赖于X,什么意思呢,eg(学号,课程)—>姓名.(学号,课程)可以唯一确定姓名,但是姓名只需要一个学号就能唯一确定,没有课程也可以,这就称B部分依赖A.

4.完全函数依赖:A属性组唯一确定B,并且A属性组的任何一个真子集不能唯一确定B。那么称B完全依赖于A.eg: (学号,课程)–>成绩.(学号,课程中的任何一个都不能唯一确定成绩),所以说成绩完全依赖于(学号,课程);

5.传递函数依赖:如果属性A–>B,B–>C,那么A–>C.且B不属于A,B也不能唯一确定A,那么A–>C.eg:学号—>系名,系名—>宿舍楼. 那么学号—>宿舍楼.为传递函数依赖.

6.码:一个属性或者属性组能唯一确定本属性或属性组之外的所有属性,即其它属性完全依赖此属性或属性组.eg(学号,课程)唯一确定(姓名,系名,宿舍楼,成绩),那么,怎样去找码呢,如果有n个属性列,那么所有的组合,一个属性的组合n种,二个属性的组合,Cn2(代表从n个中任意取两个),三个属性的组合Cn3(代表从n个中任意取三个)……….当然,不可能一个一个去试.那是有技巧的,当你已经知道(学号,课程)是码,那么以后,包含这个列的组成直接忽略.因为码是完全函数依赖.

7.主属性:码中包含的属性叫做主属性.

8.非主属性:除过码中包含的属性之外的所有属性.

9.单码:单个属性是码.

10.全码:整个属性组是码,称为全码.

6.第一范式(1NF)

如果关系模式R中不包含多值属性,则R满足第一范式.并且,关系模式中所有的属性都是不可再分事务数据项,第一范式是对关系模式的最低要求,不满足第一范式的数据库模式称为关系型数据库. 具体来看个例子吧:



在上面这个表中,学生对应(学号,姓名),明显学生既对应学号,又对应姓名.所以,这应该分开做出调整,第一张(下面这张表就满足第一范式).

学号姓名系名宿舍楼课程号成绩
03001周毅电信系A楼语文95
03001周毅电信系A楼数学89
04015崔勇计算机系C楼大物70
04015崔勇计算机系C楼英语85
03018王文涛电信系A楼语文87
03019马季军法律系B楼大物88
03020贺智平法律系B楼大物56
在看上面我们提到的4个范式我们要解决的4个问题,第一范式是否解决了上面的问题,解决了几个:

* 数据冗余可以看到姓名,系名,宿舍楼大量的重复.

* 更新异常:如果一个学生改名,则关于这个学生的所有的选课元组都得更新(eg:如果周毅改名,则需要去改两列).

* 删除异常:如果计算机的系的学生全部毕业,相应的计算机系以及C楼的信息也会被删除.

* 插入异常:如果学校新开了某个系,但是没有招学生,这个系就无法插入.

7.第二范式(2NF)

在第一范式的基础上,如果每个非主属性对主属性都达到了完全函数依赖,则满足第二范式的要求(2NF),换去话说,就是消除所有非主属性对主属性的部分函数依赖(ps:这是第二范式的要求),那么,怎么去分析呢?看我们上面的例子:

主属性:(学号,课程); ps:主属性必须是码哦.

非主属性:姓名,系,宿舍楼,成绩.

(学号,课程)—>姓名: 姓名由学号就能唯一确定,所以姓名对(学号,课程)是部分函数依赖.

(学号,课程)—>系:系和姓名一样,由学号能唯一确定.

为了消除关系模式中的部分函数依赖,采用投影分解法,将部分函数依赖从关系模式中分离出来,得到以下两张表.



SC(学号,课程,成绩);

SL(学号,姓名,系名,宿舍楼);

得到两张表分别为:

SC表

学号课程成绩
03001语文95
03001数学89
04015大物70
04015英语85
03018语文87
03019大物88
03020大物56
S表  

学号姓名系名宿舍楼
03001周毅电信系A楼
04015崔勇计算机系C楼
03018王文涛电信系A楼
03019马季军法律系B楼
03020贺智平法律系B楼
在看上面提到的4个问题我们解决了几个:

数据冗余:明显的可以看出姓名,系名,系主任的数据冗余得到了明显的改善.

更新异常:现在,一个学生改名,,只需要改S表中的姓名,而没有必要改他的每一条选课记录.

插入异常:如果现在学校新开设一个系,在没有招生的情况下,系还是不能插入到S表中,因为学号是主属性.()

删除异常:一个系的所有学生毕业,再删除所有学生信息的同时,会连带着删掉所有系的信息.

既然第二范式只是降低了数据冗余度,其它的并没有得到提高. 那么,接着,我们一起来看第三范式:

8.第三范式(3NF)

同样,第三范式是建立在第二范式的基础上.而第三范式的目的是消除非主属性对主属性的传递函数依赖.

在第二范式中,我们得到了两张表:

SC表:选课(学号,课程,成绩).

S表:(学号,姓名,系名,宿舍楼)

还记得什么是传递函数依赖吧,如果忘了,翻到上面去看看.分析SC表,我们发现,不存在传递函数依赖,而在S表(学号)–>(系名) (系名)—>(宿舍楼)存在传递函数依赖,那我们就解决了这个传递函数依赖,看看上面的问题能不能得到改善呢?

SC表:选课(学号,课程,分数)

S表:学生(学号,姓名,系名);

D表:系(系,宿舍楼);


 

得到三张表

SC表

学号课程成绩
03001语文95
03001数学89
04015大物70
04015英语85
03018语文87
03019大物88
03020大物56
S表

学号姓名系名
03001周毅电信系
04015崔勇计算机系
03018王文涛电信系
03019马季军法律系
03020贺智平法律系
D表

宿舍楼
电信系A楼
法律系B楼
计算机系C楼
再看上面的问题我们第三范式解决了几个:

插入异常:如果现在学校新开设一个系.就算没有纳入招生计划,此系还是可以插入到D表中.

删除异常,就算现在一个系中的所有学生都毕业了,删除这个系的所有学生的信息,这个系的信息也不会被删除。 

大家可以发现,到现在为止,数据冗余,更新异常,插入异常,删除异常都得到了改善.它已经能基本满足我们的需要了.

9.BC范式(BCNF)

BC范式:BC范式是在第三范式的基础上的一种特殊情况,既每个表只有一个候选键(在一个数据库中每行的值都不相同,则可称为候选键)。

每一个决定因素都为键,则R一定属于BC范式,对于BCNF的关系模式,具有以下性质:

(1)所有非主属性都完全依赖于每个主属性.(在第二范式2NF中已经实现)

(2)所有主属性对每一个不包含它的主属性都是完全函数依赖;

(3)没有任何属性完全函数依赖于非主属性中任何一组属性. (第三范式中已经实现)

那么,BC范式就是完全针对主属性而言的,即上面所说的第二条.所有主属性对每一个不包含它的主属性都是完全函数依赖;

看个具体的例子 

假设仓库管理关系表为storehourseMange(仓库ID,存储物品ID,管理员ID,数量).

仓库ID存储物品ID管理员ID数量
A1S1C120
A1S2C130
A2S3C240
A2S4C250
A2S5C260

此表满足:

一个管理员只在一个仓库工作

一个仓库可以存储多种物品

这个数据库表存在如下决定关系:

(仓库ID,存储物品ID)—->(管理员ID,数量)

(管理员ID,存储物品ID)—>(仓库ID,数量)

主属性:仓库ID,存储物品ID,管理员ID.

非主属性:数量.

码(还记得码的概念吧,不记得了翻上去看看):(仓库ID,存储物品ID),(管理员ID,存储物品ID).

先来确定这个张表是否满足第三范式(3NF),因为BCNF范式是建立在第三范式的基础之上的.

分析表可以看出.不存在非主属性对对主属性的部分函数依赖和传递函数依赖.满足第三范式.

那么先来看看上面提到的四个问题:

数据冗余:看表很明显这个问题不存在.

插入异常:如果现在新建一个仓库,但是不给这个仓库中存任何物品,那么,此条数据无法存入.

删除异常:如果某个仓库的物品全部出库,删除这个物品的同时,对应的仓库也会被删除.

更新异常:如果某个仓库换了管理员,则要改多条数据.

原因是什么呢?

看这个关系(仓库ID,)

(管理员ID,存储物品ID)—->(仓库ID);看这个关系,三个属性都是主属性,但是(管理员ID就能唯一确定仓库ID),所以仓库ID对(管理员ID,存储物品ID)存在部分函数依赖.

分解表得到:

仓库:(仓库ID,管理员ID);

物品:(仓库ID,存储物品ID,数量);

仓库:

仓库ID管理员ID
A1C1
A2C2
物品:

仓库ID存储物品ID数量
A1S120
A1S230
A2S340
A2S450
A2S560

再看刚才的问题:

插入异常: 新建一个仓库,就算里面没有东西,也可以插入仓库表.

更新异常:,某个仓库的管理员换了,则只需要改仓库表中的一条数据.

删除异常:某个仓库的物品全部出库,此仓库也不会被删除.

10.第四范式(4NF)

上面解决的是在函数依赖的范畴内有关关系模式的规范化问题,如果一个关系模式达到了BCNF,是否就完美了。看下面这个例子:

在一个教学管理系统中,有一个关系模式Teaching(C,T,B),其中C表示课程,T表示教师,B表示参考书.

存在如下关系:

一门课程由多个老师讲授,它们使用同一套参考书.

每个老师可以讲授多门课程,每本参考书可以供多门课程使用.

课程C教师T参考书B
数据库原理及应用邓宇数据库系统概论
数据库原理及应用邓宇SQL Server2000
数据库原理及应用邓宇离散数学
数据库原理及应用孙泽数据库系统概论
数据库原理及应用孙泽数据库系统概论
数据库原理及应用孙泽数据库系统概论
数据结构孙泽数据结构与算法
数据结构孙泽数据结构
数据结构孙泽离散数学
数据结构曹鹏数据结构与算法
数据结构曹鹏数据结构与算法
数据结构曹鹏离散数学
很显然:这张表是全键;

先来看上面所提到的4个问题:

数据冗余:课程,教师,参考书的有关信息大量重复存储.

插入异常:当某门课增加一个任课老师,必须插入多个元组.

更新异常:如果某门课换了老师,则必须修改多行值.

删除异常:若要删除某一本参考书,则需要删除多条记录.

这张表为什么会出现这样的问题呢?

大家先来看看这张表的关系:



一门课程有多本参考书,很明显是一对多的关系. 也就是说课程对参考书有多值依赖关系。

刚才说到了多值依赖,那么,先来看看什么叫做多值依赖:

设R(U)是属性集U上的一个关系模式,X,Y,Z是U的子集,且Z=U-X-Y.关系模式R(U)中多值依赖X–>—>Y成立,当且仅当对R(U)的任一关系r,给定的一对(x,z)值,有一组Y的值.这组值仅仅决定x的值而与z的值无关.

eg: 在上面的关系模式中,对于一个(C,B)值(数据库原理及应用,SQL Server 2000),有一组T值{邓宇,孙泽},而这组值仅仅决定于课程C(数据库原理及应用),所以T的值与B的值无关m仅由C决定,C—>—>T;

将上表分解为两个关系模式:

T(课程C,教师T) ;

B(课程C,参考书) ;

关系T

课程C教师T
数据库原理及应用邓宇
数据库原理及应用孙泽
数据结构孙泽
数据结构曹鹏
关系B

课程C参考书B
数据库原理及应用数据库系统概论
数据库原理及应用SQL Server2000
数据库原理及应用离散数学
数据结构数据结构与算法
数据结构数据结构
数据结构离散数学

看看上面的问题有没有得到改善:

信息冗余: 得到改善;

插入问题:某个课程增加老师季,只要在T表中添加一条记录就好了.

删除问题:删除一本书,也只要在BC表中删除一条记录即可.

总结一下:

上面对于数据库范式进行分解的过程中不难看出,应用的范式登记越高,则表越多。表多会带来很多问题:

查询时要连接多个表,增加了查询的复杂度.

查询时需要连接多个表,降低了数据库查询性能.

而现在的情况,磁盘空间成本基本可以忽略不计,所以数据冗余所造成的问题也并不是应用数据库范式的理由。

因此,并不是应用的范式越高越好,要看实际情况而定。第三范式已经很大程度上减少了数据冗余,并且减少了造成插入异常,更新异常,和删除异常了。我个人观点认为,大多数情况应用到第三范式已经足够,在一定情况下第二范式也是可以的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据库 数据