数据库三大范式简析
简介:
在复习某视频讲解数据库三大范式后,本章尝试用简单的方式讲解数据库三大范式。坚持真实案例分析,图形化讲解。
1.1 第一范式(1NF):字段(列)原子性问题
定义:每个字段仅仅表示实体(表)的唯一属性,则实体(表)满足第一范式设计原则。即每个字段不可再分割为多个字段。
案例观察。
表1 不符合第一范式学生表
|
姓名 |
学号 |
班级 |
学术课程(课程,成绩) |
|
张三 |
itcast0001 |
mysql01 |
mysql,59 |
|
王二 |
itcast0002 |
sql02 |
sql,58 |
表1分析: 姓名、学号以及班级字段不可分割,它们均表示学生的唯一属性。但是学生课程还可以分割成课程字段与成绩字段, 不是原子字段,因此表一不满足第一范式(1NF)。
解决方案(去复合字段)
表2 符合第一范式学生表
|
姓名 |
学号 |
班级 |
课程 |
成绩 |
|
张三 |
itcast0001 |
mysql01 |
mysql |
59 |
|
王二 |
itcast0002 |
sql02 |
sql |
58 |
表2将学生课程与成绩字段拆分,每个字段不可再分,表2的所有字段均不可再份,即表2的每个字段都满足原子性原子,因此表2满足第一范式。
第一范式的作用: 提高数据查询效率。表1中,若查询学生成绩不及格的成绩,同时需要查询课程与学生成绩,因此查询效率是比较低的。而表2 可以直接查询学生成绩,因此表2 的查询效率更高。
1.2 第二范式(2NF):复合主键部分依赖问题
定义:在满足第一范式条件下,存在复合主键时,普通字段与主键存在部分依赖,则表不满足第二范式。
案例分析:
表3 复合主键表
|
姓名(P) |
性别 |
课程(P) |
成绩 |
开课时间 |
考试时间 |
|
张三 |
男 |
mysql |
59 |
2020.3.8 |
2020.7.7 |
|
王二 |
女 |
sql |
58 |
2020.3.7 |
2020.7.8 |
其中,姓名和课程代表复合主键。
图1 复合主键表字段之间的依赖关系
图1中为字段之间的依赖关系图。其中姓名是性别的直接依赖主键,课程是成绩的直接依赖主键,这两个普通字段都间接依赖于姓名和课程。开课时间和考试时间由姓名和课程共同决定,因此开课时间与考试时间与复合主键(姓名,课程)存在直接依赖关系。
依赖关系分析如下:
①字段直接依关系:
性别 -直接依赖-> 姓名 -直接依赖->(姓名,课程)
成绩 -直接依赖->课程 -直接依赖-->(姓名,课程)
(开课时间、考试时间) -直接依赖>(姓名,课程)
②字段间接依赖关系:
性别 -间接依赖->(姓名,课程)
成绩 -间接依赖-->(姓名,课程)
解决方案:
- 实体分割(保留复合主键):存在复合主键时,代表表中包含多个实体,因此可以将实体分开,对每个实体分别建立一张表。最后通过映射关系(外键)将表关联起来。
- 添加逻辑主键(去复合主键):
表4 去复合主键表
|
ID(P) |
姓名 |
性别 |
课程 |
成绩 |
开课时间 |
考试时间 |
|
1 |
张三 |
男 |
mysql |
59 |
2020.3.8 |
2020.7.7 |
|
2 |
王二 |
女 |
sql |
58 |
2020.3.7 |
2020.7.8 |
表4中不存在复合主键,因此满足第二范式。
1.3 第三范式(3NF): 间接依赖问题
定义:在满足第二范式条件下,所有普通字段与主键均满足直接依赖关系的表,符合第三范式设计原则。
案例:依然对表4进行分析
表4 去复合主键表
|
ID(P) |
姓名 |
性别 |
课程 |
成绩 |
开课时间 |
考试时间 |
|
1 |
张三 |
男 |
mysql |
59 |
2020.3.8 |
2020.7.7 |
|
2 |
王二 |
女 |
sql |
58 |
2020.3.7 |
2020.7.8 |
图2 去复合主键表依赖关系图
图2中,性别直接依赖姓名,然后依赖ID,即性别与ID之间存在间接依赖。成绩直接依赖课程,然后间接依赖ID。因此表4存在间接依赖关系,不满足第三范式。
注意:表4的ID代表着(姓名,课程)复合主键,
解决方案:表拆分。将表4拆分为表5、6、7三个表。
表5 去复合主键表
|
ID(P) |
学生ID |
课程ID |
开课时间 |
考试时间 |
|
1 |
1 |
1 |
2020.3.8 |
2020.7.7 |
|
2 |
2 |
2 |
2020.3.7 |
2020.7.8 |
表6 学生表
|
学生ID(P) |
姓名 |
性别 |
|
1 |
张三 |
男 |
|
2 |
王二 |
女 |
表7课程表
|
课程ID(P) |
课程 |
成绩 |
|
1 |
mysql |
59 |
|
2 |
sql |
58 |
表5,6,7中,均不存在间接依赖的字段。因此满足第三范式设计原则。
注意:表5中ID代表复合主键,但是不存在间接依赖。表6、7中ID为普通主键,因此不存在间接依赖。
作用:消除间接依赖,可极大的去除数据冗余,节省存储空间;但是查询时,需要引入多表联查,降低了效率。
1.4逆规范化
定义:当某一子表的查询频率比较高时,会在主表中保存业务主键而非逻辑主键,以提高查询效率,但这种方式违反了范式设计原则,因此称为规范化。
设计案例:
以逆规范化设计原子对表5进行改进,以提升学生信息表查询速度设计结果如表8,9.
表8 去复合主键表
|
ID(P) |
姓名 |
课程ID |
开课时间 |
考试时间 |
|
1 |
张三 |
1 |
2020.3.8 |
2020.7.7 |
|
2 |
王二 |
2 |
2020.3.7 |
2020.7.8 |
表9 学生表
|
姓名(P) |
性别 |
|
张三 |
男 |
|
王二 |
女 |
表8为主表,表9为子表,在表8中保存的直接保存表9的业务主键(姓名)。
作用:逆规范化增加了数据冗余,但是提高了数据查询效率,有利于提升客户体验度。