多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[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 丢失了, 因而对原来的语义有所破坏。没有体现出每个仓库里一种部件由专人负责。有可能出现 一部件由两个人或两个以上的人来同时管理。因此,分解之后的关系模式降低了部分完整性约束。 ## *第四范式:* 要求把同一表内的多对多关系删除。 ## *第五范式:* 从最终结构重新建立原始结构。 > 并且,**某些情况下,过于范式化甚至会对数据库的逻辑可读性和使用效率起到阻碍**。数据库中一定程度的冗余并不一定是坏事情。 **但在绝大多数应用中不需要设计到第四和第五这两种程度**。如果你对第四范式、第五范式感兴趣可以看一看专业教材,从头学起,并且忘记我说的一切,以免对你产生误导。