数据库"范式"

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/whoamiyang/article/details/51832918

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 数量
A1 S1 C1 20
A1 S2 C1 30
A2 S3 C2 40
A2 S4 C2 50
A2 S5 C2 60

此表满足:

  • 一个管理员只在一个仓库工作
  • 一个仓库可以存储多种物品
    这个数据库表存在如下决定关系:
    (仓库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
A1 C1
A2 C2

物品:

仓库ID 存储物品ID 数量
A1 S1 20
A1 S2 30
A2 S3 40
A2 S4 50
A2 S5 60

再看刚才的问题:

  • 插入异常: 新建一个仓库,就算里面没有东西,也可以插入仓库表.
  • 更新异常:,某个仓库的管理员换了,则只需要改仓库表中的一条数据.
  • 删除异常:某个仓库的物品全部出库,此仓库也不会被删除.

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表中删除一条记录即可.

总结一下:

  • 上面对于数据库范式进行分解的过程中不难看出,应用的范式登记越高,则表越多。表多会带来很多问题:
  • 查询时要连接多个表,增加了查询的复杂度.
  • 查询时需要连接多个表,降低了数据库查询性能.
  • 而现在的情况,磁盘空间成本基本可以忽略不计,所以数据冗余所造成的问题也并不是应用数据库范式的理由。
  • 因此,并不是应用的范式越高越好,要看实际情况而定。第三范式已经很大程度上减少了数据冗余,并且减少了造成插入异常,更新异常,和删除异常了。我个人观点认为,大多数情况应用到第三范式已经足够,在一定情况下第二范式也是可以的。

猜你喜欢

转载自blog.csdn.net/whoamiyang/article/details/51832918