1.2.3 关系数据库的规范化

关系数据库的规范化理论是,关系数据库中的每一个关系都要满足一定的规范。根据满足规范的条件不同,可以分为5个等级:第一范式(1NF)、第二范式(2NF)……第五范式(5NF)。其中,NF是normal form的缩写。一般情况下,只要把数据规范到第三范式标准就可以满足需要。下面举例介绍前3种范式。

1.第一范式

第一范式是指在一个关系中,消除重复字段,且各字段都是最小的逻辑存储单位。第一范式是第二范式和第三范式的基础,是最基本的范式。第一范式包括下列指导原则。

(1)数据组的每个属性只可以包含一个值。

(2)关系中的每个数组必须包含相同数量的值。

(3)关系中的每个数组一定不能相同。

在任何一个关系数据库中,第一范式是对关系模式的基本要求,不满足第一范式的数据库就不是关系型数据库。

如果数据表中的每一列都是不可再分割的基本数据项,即同一列中不能有多个值,那么就称此数据表符合第一范式,由此可见第一范式具有不可再分解的原子特性。

在第一范式中,数据表的每一行只包含一个实体的信息,并且每一行的每一列只能存放实体的一个属性。例如,对于学生信息,不可以将学生实体的两个或多个或所有属性信息(如学号、姓名、性别、年龄、班级等)都放在一个列中予以显示,也就是说,一个列中应只存放学生实体的一个属性信息。

如果数据表中的列信息都符合第一范式,那么在数据表中的字段都是单一的、不可再分的。如表1.1就是不符合第一范式的学生信息表,因为“班级”列中包含“系别”和“班级”两个属性信息,这样“班级”列中的信息就不是单一的,是可以再分的;而表1.2就是符合第一范式的学生信息表,它将原“班级”列的信息拆分到“系别”列和“班级”列中。

表1.1 不符合第一范式的学生信息表

表1.2 符合第一范式的学生信息表

2.第二范式

第二范式是在第一范式的基础上建立起来的,即满足第二范式必先满足第一范式。第二范式要求数据库表中的每个实体(即各个记录行)必须可以被唯一地区分。为实现区分各行记录,通常需要为表设置一个“区分列”,用以存储各个实体的唯一标识。在学生信息表中,设置了“学号”列,由于每个学生的编号都是唯一的,因此每个学生可以被唯一地区分(即使学生存在重名的情况),这个唯一属性列被称为主关键字或主键。

第二范式要求实体的属性完全依赖于主关键字,即不能存在仅依赖于主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该被分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。

例如,这里以员工工资信息表为例,若以员工编码、岗位为组合关键字(即复合主键),就会存在如下决定关系。

     (员工编码、岗位)→(决定)(姓名、年龄、学历、基本工资、绩效工资、奖金)

在上面的决定关系中,还可以进一步被拆分为如下两种决定关系。

     (员工编码)→(决定)(姓名、年龄、学历)
     (岗位)→(决定)(基本工资)

其中,员工编码决定了员工的基本信息(包括姓名、年龄、学历等),而岗位决定了基本工资,因此这个关系表不满足第二范式。

对于上面的这种关系,可以把上述两个关系表更改为如下3个表。

员工信息表:EMPLOYEE(员工编码、姓名、年龄和学历)。

岗位工资表:QUARTERS(岗位和基本工资)。

员工工资表:PAY(员工编码、岗位、绩效工资和奖金)。

3.第三范式

第三范式是在第二范式的基础上建立起来的,即满足第三范式必先满足第二范式。第三范式要求关系表不存在非关键字列对任意候选关键字列的传递函数依赖,也就是说,第三范式要求一个关系表中不包含已在其他表中包含的非主关键字信息。

所谓传递函数依赖,是指如果存在关键字段A决定非关键字段B,而非关键字段B决定非关键字段C,则称非关键字段C传递函数依赖于关键字段A。

例如,这里以员工信息表(EMPLOYEE)为例,该表中包含员工编码、员工姓名、年龄、部门编码、部门经理等信息,该关系表的关键字为“员工编码”,因此存在如下决定关系。

     (员工编码)→(决定)(员工姓名、年龄、部门编码、部门经理)

上面的这个关系表是符合第二范式的,但它不符合第三范式,因为该关系表内部隐含着如下决定关系。

     (员工编码)→(决定)(部门编码)→(决定)(部门经理)

上面的关系表存在非关键字段“部门经理”对关键字段“员工编码”的传递函数依赖。对于上面的这种关系,可以把这个关系表(EMPLOYEE)更改为如下两个关系表。

员工信息表:EMPLOYEE(员工编码、员工姓名、年龄和部门编码)。

部门信息表:DEPARTMENT(部门编码和部门经理)。

对于关系型数据库的设计,理想的设计目标是按照“规范化”原则存储数据的,因为这样做能够消除数据冗余、更新异常、插入异常和删除异常。