在学习数据库范式的时候,很多人搞不清第二范式和第三范式他到底是有啥区别。
想讲清楚第二范式与第三范式的区别,不得不聊到键和相关属性的概念
键和相关属性的概念
范式的定义会使用到主健和候选健,数据库中的健(Key)由一个或者多个属性组成。数据表中常用的几种键和属性的定义:
- 超键∶能唯一标识元组的属性集叫做超键
- 候选键︰如果超键不包括多余的属性,那么这个超键就是候选键
- 主键:用户可以从候选键中选择一个作为主键
- 外键:如果数据表R1中的某属性集不是R1的主键,而是另一个数据表R2的主键,那么这个属性集就是数据表R1的外键
- 主属性:包含在任一候选键中的属性称为主属性
- 非主属性:与主属性相对,指的是不包含在任何一个候选键中的属性
通常也将候选键称之为“码”,把主键也称为“主码"。因为键可能是由多个展性组成的,针对单个属性,还可以用主属性和非主属性来进行区分
举例:
这里有两个表:
球员表(player):球员编号│姓名|身份证号|年龄|球队编号
球队表(team):球队编号|主教练|球队所在地
- 超键∶对于球员表来说,超键就是包括球员编号或者身份证号的任意组合,比如(球员编号)(球员编号,姓名)(身份证号,年龄)等
- 候选键∶就是最小的超键,对于球员表来说,候选键就是(球员编号〕或者(身份证号)
- 主键 :我们自己选定,也就是从候选键中选择一个,比如(球员编号)
- 外键 :球员表中的球队编号
- 主属性 、 非主属性 :在球员表中,主属性是(球员编号)(身份证号),其他的属性(姓名)(年龄)(球队编号)都是非主属性
现在我们已经对键和相关属性的概念有了认识,接下来我们来看
第二范式
第二范式要求,在满足第一范式的基础上,还要满足数据表里的每一条数据记录,都是可唯一标识的。而且所有非候选键字段,都必须完全依赖候选键,即不能存在可以依赖候选键的一部分
这里说的,完全依赖候选主键,很重要,意味着不能存在任何其他的依赖。
我们举例一个不满足第二范式的例子
不满足第二范式 举例:
比赛表 player_game ,里面包含球员编号、姓名、年龄、比赛编号、比赛时间和比赛场地等属性,这里候选键为(球员编号,比赛编号),我们可以通过候选键来决定如下的关系:
(球员编号, 比赛编号) → (姓名, 年龄, 比赛时间, 比赛场地,得分)
他们的依赖关系如下
满足第二范式的举例:
我们可以根据上面的表的设计修改分成三张表,以满足第二范式
即每张表是一个独立的对象,一张表只表达一个意思
第三范式
第三范式是在第二范式的基础上,确保数据表中的每一个非主键字段都和主键字段直接相关,也就是说,要求数据表中的所有非主键字段不能依赖于其他非主键字段。
〈即,不能存在非主属性A依赖于非主属性B,非主属性B依赖于主键c的情况,即存在"A一B一C"的决定关系)通俗地讲,该规则的意思是所有非主键属性之间不能有依赖关系,必须相互独立。
这里的主键可以拓展为候选键。
我们举一个符合第二范式,但显然不符合第三范式的例子
下面这个是符合第二范式的,因为这里就一个主键,并且其他所有字段都完全依赖于球员编号这一个唯一的主键。
不满足第三范式是因为内部存在 非主键依赖的关系 球队教练和球队名称之间存在依赖。
这里一定要区分好,因为第二范式是需要与主键存在完全依赖,也就是说需要完全依赖于主键球员编号和比赛编号。
而第三范式说的是,不能存在非主键之间的相互依赖
由此你就可以了解到第二范式和第三范式的区别了
第二范式要求 所有非候选键字段,都必须完全依赖候选键
第三范式要求,不但 所有非候选键字段,都必须完全依赖候选键,而且所有的非主键之间,不可存在相互依赖
,即不可存在某个字段与主键间接关联的情况。
显然这个不符合第三范式,因为球队教练和球员编号其实是间接关联的,依靠一个非主键球队名称。