这篇文章简单介绍一下数据库的1NF范式、2NF范式、3NF范式。
1NF范式要求数据库中不能有可以继续拆分的列,使数据库满足1NF范式要求的方法是拆分列。实例如下:
姓名 | 电话 |
---|---|
张三 | 手机:18000001111,固话:010-99001100 |
这样一张表不满足1NF的要求,因为电话那一列显然可以拆分为多个列,拆分之后如下:
姓名 | 手机 | 固定电话 |
---|---|---|
张三 | 18000001111 | 010-99001100 |
1NF 通常很难违背,现代DBMS列是最小单位,除非故意,否则不可能设计出违背1NF的数据表
2NF通俗的说就是有主键的同时没有部分依赖,部分依赖指的是一些非主属性依赖于主键的一部分,而不是主键的全部,使数据库满足2NF的方法是拆分表。实例如下:
学号 | 课程号 | 课程名称 | 成绩 |
---|---|---|---|
01 | 01 | 操作系统 | 99 |
这个表的主键是学号和课程号(学号,课程号),而课程名称只依赖于课程号,是部分依赖于主键的,不满足2NF,主键和依赖情况如下:
主键(学号,课程号)
依赖(学号,课程号)–>成绩,课程号–>课程名称,第二个是部分依赖
需要进行拆分
1 课程表
课程号 | 课程名称 |
---|---|
01 | 操作系统 |
2 选课表
学号 | 课程号 | 成绩 |
---|---|---|
01 | 01 | 99 |
这样以上两个表的的主键和依赖如下,则不存在部分依赖:
1 课程表
课程号是主键,依赖为 课程号–>课程名称
2 选课表
(课程号,学号)是主键,依赖为(学号,课程号)–> 成绩
3NF 是在2NF的基础上消除传递依赖的情况,例如以下数据表,满足2NF,但存在传递依赖,不满足3NF
学号 | 姓名 | 班号 | 班级名称 |
---|---|---|---|
120101 | 张三 | 1201 | 计科1班 |
上表不满足3NF,下面是主键和依赖:
主键:学号
依赖:学号–>姓名,学号–>班号,学号–>班级名称,但是其中的学号–>班级名称是传递依赖,因为班级名称依赖于班号,所以实际的依赖情况是学号–>班号–>班级名称,产生了传递依赖,进行如下拆分即可去掉依赖
1 学生表
学号 | 姓名 | 班号 |
---|---|---|
120101 | 张三 | 1201 |
2 班级表
班号 | 班级名称 |
---|---|
1201 | 计科1班 |
1NF 列不可再分
判断2NF M-N 型关系中掺杂了M或N所属的表的一些数据(选课(学生-课程)掺杂了课程名称)
判断3NF 1-N 型关系中掺杂了M或N所属的表的一些数据(学生(班级-学生)掺杂了班级名称)
是“符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度”。在进入范式的讲解前,需要先了解5个概念:“函数依赖”、“完全函数依赖”、“传递函数依赖”“码”、“非主属性”。
可以这么理解(但并不是特别严格的定义):若在一张表中,在属性(或属性组)X的值确定的情况下,必定能确定属性Y的值,那么就可以说Y函数依赖于X,写作 X → Y。也就是说,在数据表中,不存在任意两条记录,它们在X属性(或属性组)上的值相同,而在Y属性上的值不同。这也就是“函数依赖”名字的由来,类似于函数关系 y = f(x),在x的值确定的情况下,y的值一定是确定的。
在一张表中,若 X → Y,且对于 X 的任何一个真子集(假如属性组 X 包含超过一个属性的话),X ’ → Y 不成立,那么我们称 Y 对于 X 完全函数依赖,记作X F→ Y
例如:
学号 F→ 姓名
(学号,课名) F→ 分数 (注:因为同一个的学号对应的分数不确定,同一个课名对应的分数也不确定)
反之为部分函数依赖,记作X P→ Y
例如:
(学号,课名) P→ 姓名 (注:因为仅由学号就可以确定姓名)
传递函数依赖:
假如 Z 函数依赖于 Y,且 Y 函数依赖于 X (在『Y不包含于X,且 X 不函数依赖于 Y』这个前提下),那么就称 Z 传递函数依赖于 X ,记作 X T→ Z
码:
设 K 为某表中的一个属性或属性组,若除 K 之外的所有属性都完全函数依赖于 K(这个“完全”不要漏了),那么我们称 K 为候选码,简称为码。在实际中通常可以理解为:假如当 K 确定的情况下,该表除 K 之外的所有属性的值也就随之确定,那么 K 就是码。一张表中可以有超过一个码。(实际应用中为了方便,通常选择其中的一个码作为主码)
包含在任何一个码中的属性称为主属性,反之则为非主属性。
码:表中可以唯一确定一个元组的某个属性(或者属性组),如果这样的码有不止一个,那么大家都叫 候选码,我们从候选码中挑一个出来做老大,它就叫主码。
全码:如果一个码包含了所有的属性,这个码就是全码。
主属性:一个属性只要在任何一个候选码中出现过,这个属性就是主属性。
非主属性:与上面相反,没有在任何候选码中出现过,这个属性就是非主属性。
外码:一个属性(或属性组),它不是码,但是它别的表的码,它就是外码。
候选码: 若关系中的某一属性或属性组的值能唯一的标识一个元组,而其任何真子集都不能再标识,则称该属性组为(超级码)候选码。