[TOC]
# 简介
好了,上面已经介绍了我们掌握范式所需要的全部基础概念,下面我们就来讲范式。 范式可以理解为一种规范等级。
首先要明白,范式的包含关系:
> 一个数据库设计如果符合第二范式,一定也符合第一范式。如果符合第三范式,一定也符合第二范式…
## **第一范式(1NF):属性不可分。**
第一范式的特点:
* 有主关键字
* 主键不能为空
* 主键不能重复
* 字段不可以再分
下表是否满足第一范式?
| StudyNo | Name| Sex | Contact |
| -- | -- | -- | -- |
| 20040901 | john | Male | Email:kkkk@ee.net,phone:222456 |
| 20040901 | mary| Female | Email:kkk@fff.net phone:123455 |
Ps:这个表中,属性值“分”了:
![](https://box.kancloud.cn/94c991bb62fb987d5994cab7f5151713_425x87.png)
Ps:这个表中,属性值“分”了:
![](https://box.kancloud.cn/640d42694a00d68dcdf01a8fd9b97cad_425x115.png)
以上表格都是否满足第一范式?(**不满足属性不可分!**)
**注意:** 这两种情况都不满足第一范式。不满足第一范式的数据库,不是关系数据库!所以,我们在任何关系数据库管理系统中,做不出这样的“表”来。
## **第二范式(2NF):非主属性完全依赖于码。**
定义:如果关系模式R是第一范式的,而且关系中每一个非主属性不部分依赖于主键,称R是第二范式的。
所以第二范式的主要任务就是满足第一范式的前提下,消除部分函数依赖。
观察这个表格是否满足第二范式:
| StudyNo | Name | Sex | Email |Phone | ClassNo |ClassAddress |
| -- | -- | -- | -- | -- | -- | -- |
| 01 | john | Male | k@ee.net | 222456 | 200401| A楼2单元 |
| 02 | mary | Female | kkk@fff.net | 123455 | 200402 | A楼3单元 |
这个表完全满足于第一范式主键由`StudyNo`和`ClassNo`组成,这样才能定位到指定行,但是,`ClassAddress`部分依赖于关键字(`ClassNo-〉ClassAddress`),所以要变为两个表:
表一:
| StudyNo | Name | Sex | Email |Phone | ClassNo |
| -- | -- | -- | -- | -- | -- | -- |
| 01 | john | Male | k@ee.net | 222456 | 200401|
| 02 | mary | Female | kkk@fff.net | 123455 | 200402 |
表二:
| ClassNo |ClassAddress |
| -- | -- |
| 200401| A楼2单元 |
| 200402 | A楼3单元 |
### **再来看一个例子:**
![2015-08-11/55c974dc2c250](http://box.kancloud.cn/2015-08-11_55c974dc2c250.png)
**分析:**
一个学生上一门课,一定在特定某个教室。所以有(学生,课程)->教室
一个学生上一门课,一定是特定某个老师教。所以有(学生,课程)->老师
一个学生上一门课,他老师的职称可以确定。所以有(学生,课程)->老师
一个学生上一门课,一定是特定某个教材。所以有(学生,课程)->教材
一个学生上一门课,一定在特定时间。所以有(学生,课程)->上课时间
因此(学生,课程)是一个码。
然而,一个课程,一定指定了某个教材,一年级语文肯定用的是《小学语文1》
那么就有课程->教材。(学生,课程)是个码,课程却决定了教材,这就叫
不完全依赖,或者说部分依赖。出现这样的情况,就不满足第二范式!
**思考:**
那么,如果我们希望他满足第二范式,仿照刚才的例子我们应该怎样做了?
**解决:**
1. 校长要新增加一门课程叫“微积分”,教材是《大学数学》,怎么办?学生还没选课,而学生又是主属性,主属性不能空,课程怎么记录呢,教材记到哪呢(插入异常)
2. 下学期没学生学一年级语文(上)了,学一年级语文(下)去了,那么表中将不存在一年级语文(上),也就没了《小学语文1》。这时候,校长问:一年级语文(上)用的什么教材啊?……郁闷了吧?(删除异常)
3. 校长说:一年级语文(上)换教材,换成《大学语文》。有10000个学生选了这么课,改动好大啊!改累死了……郁闷了吧?(修改异常)那应该怎么解决呢?投影分解,将一个表分解成两个或若干个表。
**解决:**
![2015-08-11/55c9777bbb1cd](http://box.kancloud.cn/2015-08-11_55c9777bbb1cd.png)
## **第三范式(3NF)(不依赖于其它非主属性[消除传递依赖] )。**
| StudyNo | Name | Sex | Email | bounsLevel | bouns |
| -- | -- | -- | -- | -- | -- |
| 40901 | john | Male | kkkk@ee.net | 良 | $1000 |
| 40902 | mary | female | kkk@fff.net | 差 | $600 |
这个完全满足了第二范式,但是`bounsLevel`和`bouns`存在传递依赖。
**解决:**
更改为:
表一:
| StudyNo|Name | Sex | Email| bounsNo |
| -- | -- | -- | -- | -- |
| 20040901 | john | Male | kkkk@ee.net | 1 |
| 20040902 | mary | Female | kkk@fff.net | 2 |
表二:
| bounsNo | bounsLevel | bouns |
| -- | -- | -- |
| 1 | 优秀 | $1000 |
| 2 | 良 | $600 |
### 再来看一个示例:
![2015-08-11/55c97a35ea926](http://box.kancloud.cn/2015-08-11_55c97a35ea926.png)
有什么问题吗?
想想:
1. 老师升级了,变教授了,要改数据库,表中有N条,改了N次……(修改异常)
2. 没人选这个老师的课了,老师的职称也没了记录……(删除异常)
3. 新来一个老师,还没分配教什么课,他的职称记到哪?……(插入异常)
那应该怎么解决呢?和上面一样,投影分解:
| 学生 | 课程 | 老师| 教室| 上课时间 |
|---- |---|---| -- |---|
| 小明 | 小明 | 大宝 | 101 | 14:30 |
| 老师 | 老师职称 |
|---- |---|---|
| 大宝 | 副教授 |
## BC范式(BCNF):符合3NF,并且,主属性不依赖于主属性
若关系模式属于第一范式,且每个属性都不传递依赖于键码,则R属于BC范式。
通常BC范式的条件有多种等价的表述:每个非平凡依赖的左边必须包含键码;每个决定因素必须包含键码。
BC范式既检查非主属性,又检查主属性。当只检查非主属性时,就成了第三 范式。满足BC范式的关 系都必然满足第三范式。
还可以这么说:**若一个关系达到了第三范式,并且它只有一个候选码,或者它的每个候选码都是单属性,则该关系自然达到BC范式。**
一般,一个数据库设计符合3NF或BCNF就可以了。在BC范式以上还有第四范式、第五范式。
### 详解:
如果关系模式R(U,F)的所有属性(包括主属性和非主属性)都不传递依赖于R的任何候选关键字,那么称关系R是属于BCNF的。或是关系模式 R,如果每个决定因素都包含关键字(而不是被关键字所包含),则RCNF的关系模式。
例:配件管理关系模式 WPE(WNO,PNO,ENO,QNT)分别表仓库号,配件号,职工号,数量。
有以下条件:
* 一个仓库有多个职工。
* 一个职工仅在一个仓库工作。
* 每个仓库里一种型号的配件由专人负责,但一个人可以管理几种配件。
* 同一种型号的配件可以分放在几个仓库中。
分析:
由以上得 PNO 不能确定QNT,由组合属性(WNO,PNO)来决定,存在函数依赖(WNO,PNO) -> ENO。由于每个仓库里的一种配件由专人负责,而一个人可以管理几种配件,所以有组合属性(WNO,PNO)才能确定负责人,有(WNO,PNO)- > ENO。因为 一个职工仅在一个仓库工作,有ENO -> WNO。由于每个仓库里的一种配件由专人负责,而一个职工仅在一个仓库工作,有 (ENO,PNO)-> QNT。
找一下候选关键字,因为(WNO,PNO) -> QNT,(WNO,PNO)-> ENO ,因此 (WNO,PNO)可以决定整个元组,是一个候选关键字。根据ENO->WNO,(ENO,PNO)->QNT,故(ENO,PNO)也能决 定整个元组,为另一个候选关键字。属性ENO,WNO,PNO 均为主属性,只有一个非主属性QNT。它对任何一个候选关键字都是完全函数依赖的,并且是直接依赖,所以该关系模式是3NF。
分析一下主属性。因为ENO->WNO,主属性ENO是WNO的决定因素,但是它本身不是关键字,只是组合关键字的一部分。这就造成主属性WNO对 另外一个候选关键字(ENO,PNO)的部 分依赖,因为(ENO,PNO)-> ENO但反过来不成立,而P->WNO,故(ENO,PNO)-> WNO 也是传递依赖。
虽然没有非主属性对候选关键辽的传递依赖,但存在主属性对候选关键字的传递依赖,同样也会带来麻烦。如一个新职工分配到仓库工作,但暂时处于实习阶段,没 有独立负责对某些配件的管理任务。由于缺少关键字的一部分PNO而无法插入到该关系中去。又如某个人改成不管配件了去负责安全,则在删除配件的同时该职工 也会被删除。
解决办法:
分成管理EP(ENO,PNO,QNT),关键字是(ENO,PNO)工作EW(ENO,WNO)其关键字是ENO
缺点:分解后函数依赖的保持性较差。如此例中,由于分解,函数依赖(WNO,PNO)-> ENO 丢失了, 因而对原来的语义有所破坏。没有体现出每个仓库里一种部件由专人负责。有可能出现 一部件由两个人或两个以上的人来同时管理。因此,分解之后的关系模式降低了部分完整性约束。
## *第四范式:*
要求把同一表内的多对多关系删除。
## *第五范式:*
从最终结构重新建立原始结构。
> 并且,**某些情况下,过于范式化甚至会对数据库的逻辑可读性和使用效率起到阻碍**。数据库中一定程度的冗余并不一定是坏事情。
**但在绝大多数应用中不需要设计到第四和第五这两种程度**。如果你对第四范式、第五范式感兴趣可以看一看专业教材,从头学起,并且忘记我说的一切,以免对你产生误导。