携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情
一、范式
1、范式简介
在关系型数据库中,关于数据表设计的基本原则、规则就称为范式。可以理解为,一张数据表的设计结构需要满足的某种设计标准的 级别 。要想设计一个结构合理的关系型数据库,必须满足一定的范式。
2、范式都包括哪些
目前关系型数据库有六种常见范式,按照范式级别,从低到高分别是:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
3、键和相关属性的概念
举例这里有两个表:
球员表(player) :球员编号 | 姓名 | 身份证号 | 年龄 | 球队编号
球队表(team) :球队编号 | 主教练 | 球队所在地
- 超键 :对于球员表来说,超键就是包括球员编号或者身份证号的任意组合,比如(球员编号)(球员编号,姓名)(身份证号,年龄)等。
- 候选键 :就是最小的超键,对于球员表来说,候选键就是(球员编号)或者(身份证号)。
- 主键 :我们自己选定,也就是从候选键中选择一个,比如(球员编号)。
- 外键 :球员表中的球队编号。
- 主属性 、 非主属性 :在球员表中,主属性是(球员编号)(身份证号),其他的属性(姓名)(年龄)(球队编号)都是非主属性。
二、第一范式(1st NF)
举例一:假设一家公司要存储员工的姓名和联系方式。它创建一个如下表:
该表不符合 1NF ,因为规则说“表的每个属性必须具有原子(单个)值”,lisi和zhaoliu员工的emp_mobile 值违反了该规则。为了使表符合 1NF ,我们应该有如下表数据:
举例二:user 表的设计不符合第一范式
其中,user_info字段为用户信息,可以进一步拆分成更小粒度的字段,不符合数据库设计对第一范式的要求。将user_info拆分后如下:
三、第二范式(2nd NF)
举例1:成绩表 (学号,课程号,成绩)关系中,(学号,课程号)可以决定成绩,但是学号不能决定成绩,课程号也不能决定成绩,所以“(学号,课程号)→成绩”就是 完全依赖关系 。
举例2:比赛表 player_game ,里面包含球员编号、姓名、年龄、比赛编号、比赛时间和比赛场地等属性,这里候选键和主键都为(球员编号,比赛编号),我们可以通过候选键(或主键)来决定如下的关系:(球员编号, 比赛编号) → (姓名, 年龄, 比赛时间, 比赛场地,得分)
但是这个数据表不满足第二范式,因为数据表中的字段之间还存在着如下的对应关系:
(球员编号) → (姓名,年龄)
(比赛编号) → (比赛时间, 比赛场地)
对于非主属性来说,并非完全依赖候选键。这样会产生怎样的问题呢?
- 数据冗余 :如果一个球员可以参加 m 场比赛,那么球员的姓名和年龄就重复了 m-1 次。一个比赛也可能会有 n 个球员参加,比赛的时间和地点就重复了 n-1 次。
- 插入异常 :如果我们想要添加一场新的比赛,但是这时还没有确定参加的球员都有谁,那么就没法插入。
- 删除异常 :如果我要删除某个球员编号,如果没有单独保存比赛表的话,就会同时把比赛信息删除掉。
- 更新异常 :如果我们调整了某个比赛的时间,那么数据表中所有这个比赛的时间都需要进行调整,否则就会出现一场比赛时间不同的情况。
为了避免出现上述的情况,我们可以把球员比赛表设计为下面的三张表。
这样的话,每张数据表都符合第二范式,也就避免了异常情况的发生。
1NF 告诉我们字段属性需要是原子性的,而 2NF 告诉我们一张表就是一个独立的对象,一张表只表达一个意思。
四、总结
本篇主要介绍了数据库的设计规范,常见的范式有哪些?通过举例还说明第一范式和第二范式的规则,下一篇接着后续的范式介绍。