目录
什么是数据库设计范式?
数据库设计范式的好处和不足
一、第一范式(1NF)
二、第二范式(2NF)
三、第三范式(3NF)
我们设计数据库的目的是什么?当然是为了我们使用起来方便,管理起来方便等等。这样,我们就需要一套科学的、规则的规范来满足它。
范式的英文名称是 Normal Form,它是英国人 E.F.Codd(关系数据库的老祖宗)在上个世纪70年代提出关系数据库模型后总结出来的,范式是关系数据库理论的基础,也是我们在设计数据库结构过程中所要遵循的规则和指导方法。目前有迹可寻的共有8种范式,依次是:1NF,2NF,3NF,BCNF,4NF,5NF,DKNF,6NF。通常所用到的只是前三个范式,即:第一范式(1NF),第二范式(2NF),第三范式(3NF)。
好处:数据库的设计范式是数据库设计所需要满足的规范,刚刚也说过,它是为了满足我们使用和管理的需要,由此可见,它是对原先数据的优化,使我们处理数据更为便利。
不足:数据往往种类繁多,而且每种数据之间又互相关联,因此,在设计数据库时,所需要满足的范式越多,那表的层次及结构也就越复杂,最终造成数据的处理困难。这样,还不如不满足这些范式呢。所以在使用范式的时候也要细细斟酌,是否一定要使用该范式,必须根据实际情况做出选择。一般情况下,我们使用前三个范式已经够用了,不再使用更多范式,就能完成对数据的优化,达到最优效果。
规范定义:第一范式是指数据库表中的每一列都是不可分割的基本数据项;同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。
有两个点:实体的属性的不可分割性(原子性)、实体的属性的不重复性 / 不能有多个值。
解释一下实体和属性:就好比一个客户(实体),他有姓名(属性),年龄(属性),电话(属性),地址(属性)等属性。说通俗点就是表中的一行数据。
1.实体的属性的不可分割性(原子性)
这个说的就是实体的属性不可再分,就好比一个人的电话号码分为三种:手机号码、家庭电话以及办公电话。这样,我们在设计表时,就不能这样设计:
Name | Class | Age | Sex | Tel |
ZhangSan | 1 | 20 | man | 111 |
LiSi | 2 | 20 | woman | 222 |
WangWu | 3 | 20 | man | 333 |
而应该这样设计:
Name | Class | Age | Sex | MobilePhone | HomeTel | WorkTel |
ZhangSan | 1 | 20 | man | 111 | 222 | 333 |
LiSi | 2 | 20 | woman | 111 | 444 | 666 |
WangWu | 3 | 20 | man | 222 | 111 | 555 |
2.实体的属性的不重复性 / 不能有多个值(其实就是一个属性栏里不能出现多个值,毕竟同一个属性栏中的值的属性也必然是一样的)
即不能出现多个或者是重复的实体的属性。注意,这里是属性的不重复或单一性,什么叫属性不重复?打个比方,如手机号码、家庭电话以及办公电话三者都属于电话号码这一属性,而当我们在设计表时,在电话号码这一属性中就可能会出现这个人的三个号码,刚也说了,这三个号码都属于电话号码这一属性,因此属于相同属性,这样就违反了实体的属性的不重复性这一特性。又因为三个号码出现在了同一个属性中,因此也就同时违反了实体的属性不能有多个值这一特性。
例如:
Name | Class | Age | Sex | Tel |
ZhangSan | 1 | 20 | man | 111,222,333 |
LiSi | 2 | 20 | woman | 111,444,666 |
WangWu | 3 | 20 | man | 222,111,555 |
显然,我们可以看到,Tel这一栏存放的是客户的联系电话,但是对于每个客户而言,他们都具有三个电话(手机号码、家庭电话以及办公电话),这样,我们在设计时就不能将这三个相同的属性放在同一个属性列表当中,因此,上面这张表违反了数据库设计的第一范式。具体解决方案如下:
Name | Class | Age | Sex | TelNum |
ZhangSan | 1 | 20 | man | 1 |
LiSi | 2 | 20 | woman | 2 |
WangWu | 3 | 20 | man | 3 |
如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。第一范式的模式要求属性值不可再分裂成更小部分,即属性项不能是属性组合或是由一组属性构成。
TelNum | MobilePhone | HomeTel | WorkTel |
1 | 111 | 222 | 333 |
2 | 111 | 444 | 666 |
3 | 222 | 111 | 555 |
1NF是关系模式应具备的最起码的条件,如果数据库设计不能满足第一范式,就不能被称为关系型数据库。也就是说,只要是关系型数据库,就一定要满足第一范式。
是在第一范式( 1NF) 的基础上建立起来的,即满足第二范式( 2NF)必须先满足第一范式( 1NF)。
规范定义:如果关系模型R为第一范式,并且数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖,即符合第二范式。R中的每一个非主属性完全函数依赖于R的某个候选键,则称R为第二范式(如果A是关系模式R的候选键的一个属性,则称A是R的主属性,否则称A是R的非主属性)。
主属性:存在于所有候选键中的属性,称之为主属性。
候选键(候选关键字段):就是可以区别一个个实体的最少属性组合,是每个实体的唯一标识。一个表可能有多个候选键,从这些候选键中选择一个作为主键。
部分函数依赖:一个属性与另一个属性不完全相关。
完全函数依赖:一个属性与另一个属性完全相关。(下面会详细解释)
比如,一个学生信息表,其中每一个学生都拥有Id,Name,Age,Sex,Add等属性,我们假设Id存放的是学生的身份证号码,这样Id就可以作为每个学生的唯一标识,那么这个Id就可以被称为候选键。又因为它作为每个学生的唯一标识,那么我们可以理解为它与其他属性完全相关,这就是完全函数依赖。
这时,我们假设Id和Name作为学生的唯一标识,也就是候选键,这样做显然是不行的。因为即使去掉Name,我们也同样可以确定一个学生,也就是说,作为候选键的属性组合,必须都有自己的作用。而且,假设又出现了一个字段(属性)银行卡号,那么,这个银行卡号仅与Id有关,而不与Name相关,这样,就出现了非关键字段对候选关键字段的部分函数依赖,那么这个属性组合是不符合要求的,应当重新选择。
举个例子:
学号 | 课程号 | 姓名 | 课程名 | 专业 | 成绩 |
01 | 0001 | ZhangSan | 英语 | 计科 | 99 |
02 | 0002 | LiSi | 数学 | 软件 | 98 |
03 | 0002 | WangWu | 数学 | 化工 | 99 |
该表中一个学生可以选多门课,一门课有多个学生,学生姓名可能出现重名。因此学号和课程号可以唯一确定一条记录,因此用学号和课程号做主键。表中姓名、专业通过学号就能唯一确定,但是课程名却只与课程号有关,这样就形成了部分函数依赖,违背了第二范式。
违背第二范式将产生数据信息冗余和数据更新异常的问题。
1.数据信息冗余:出现了重复的课程号-课程名。
2.数据更新异常:假如现在有一门“计算机导论”要加入表中,但是由于没有学生考这一门课,那么这么课程就不能加入到表中(只有课程号和课程名而没有其他信息)。
解决办法:将其分为三种关系模式:学生表、课程表和成绩表
学生表:
学号 | 姓名 | 专业 |
01 | ZhangSan | 计科 |
02 | LiSi | 软件 |
03 | WangWu | 化工 |
课程表:
课程号 | 课程名 |
0001 | 英语 |
0002 | 数学 |
成绩表:
学号 | 课程号 | 成绩 |
01 | 0001 | 99 |
02 | 0002 | 98 |
03 | 0002 | 99 |
规范定义:在满足第二范式的基础上,在实体中不存在非主键属性传递函数依赖于主键属性。
传递函数依赖:A依赖于B,B依赖于C,就可以说A依赖C。
第三范式具有如下特征:
1. 每一列(属性)只有一个值。(1NF)
2. 每一行都能区分。(2NF)
3. 每一个表都不包含其他表已经包含的非主关键字信息。通俗的说:就是表中每一列都要与主键直接相关,而不是间接相关。
就比如上面的例子中,在成绩表中可以出现学号,但是不能出现与学号相关的其他信息,就是这个意思。