关系型数据库的功能依赖和规范化是数据库设计中的基础知识,本文将详细介绍相关概念和应用实例。
一、功能依赖
1.1 概念
在关系数据库中,一个属性(列)A 对另一个属性(列)B 构成功能依赖(Functional Dependency),表示对于每一个在属性 A 中的值,在属性 B 中对应一个唯一值。
举个例子:在一个学生表中,如果学生的学号唯一确定了学生的住址,则学号决定住址,可以表示成 $学号 \rightarrow 住址$。
1.2 分类
- 完全函数依赖:如果在关系 R 的任何一组候选键中,属性 A 不依赖于任何一个非主属性,则称 A 对候选键完全函数依赖。
- 部分函数依赖:如果在关系 R 的任何一组候选键中,属性 A 仍然依赖于某个非主属性,则称 A 对候选键部分函数依赖。
- 传递函数依赖:若对于关系 R 中任意两个属性 X、Z,如果 X→Y,Y→Z,则称 X→Z 是传递函数依赖。
二、规范化的基础知识
规范化是将反复使用的数据元素放在一个表中,以便增强数据的一致性、简化数据的存储、提高数据的查询效率。规范化的过程就是逐步消除数据冗余。
2.1 第一范式
第一范式(1NF)要求所有的数据列不可再分,即数据表的每个属性都是不可再分的基本数据项,不能再拆分成其他数据项。具体要求如下:
- 属性具有原子性:属性不可再拆分成更小的数据项。
- 属性具有唯一性:每个属性都有惟一的属性名。
举个例子:假设我们有一张学生表,其中包含学生姓名、总分、语文分数、数学分数和英语分数等属性。在第一范式下,我们需要对该表进行拆分:
学生信息表(Student):
ID | Name |
---|---|
1 | 张三 |
2 | 李四 |
3 | 王五 |
成绩表(Score):
StudentID | Subject | Score |
---|---|---|
1 | 语文 | 90 |
1 | 数学 | 80 |
1 | 英语 | 70 |
2 | 语文 | 78 |
2 | 数学 | 89 |
2 | 英语 | 90 |
3 | 语文 | 92 |
3 | 数学 | 83 |
3 | 英语 | 78 |
2.2 第二范式
第二范式(2NF)要求实体的属性能够唯一确定一条记录,即实体的属性必须完全依赖于主键,不允许只依赖于主键的部分属性。具体要求如下:
- 表必须满足第一范式。
- 非主键属性必须完全依赖于候选键(或主键)而不是部分依赖。
举个例子:在第一范式下,我们刚刚建立的成绩表中,存在部分依赖,因为科目只依赖于学生ID而不是依赖于学生ID和成绩,因此我们需要对该表进行拆分:
学生成绩表(StudentScore):
StudentID | Subject | Score |
---|---|---|
1 | 语文 | 90 |
1 | 数学 | 80 |
1 | 英语 | 70 |
2 | 语文 | 78 |
2 | 数学 | 89 |
2 | 英语 | 90 |
3 | 语文 | 92 |
3 | 数学 | 83 |
3 | 英语 | 78 |
学生信息表(Student):
ID | Name |
---|---|
1 | 张三 |
2 | 李四 |
3 | 王五 |
2.3 第三范式
第三范式(3NF)要求任何非主属性都不能依赖于其他非主属性,即不存在传递依赖。具体要求如下:
- 表必须满足第二范式。
- 所有非主属性都不依赖于其他非主属性。
举个例子:我们继续使用上面的例子,在学生表中,存在年龄与生日的冗余,因为在一个表中如果有学生的生日,就可以通过计算得到年龄,因此在第三范式下,我们需要对该表进行拆分:
学生信息表(Student):
ID | Name | Birthday |
---|---|---|
1 | 张三 | 1995-2-8 |
2 | 李四 | 1996-3-9 |
3 | 王五 | 1995-5-8 |
学生年龄表(StudentAge):
ID | Age |
---|---|
1 | 26 |
2 | 25 |
3 | 26 |
三、应用实例
假设我们有一个课程表,含有课程名、授课教师姓名和教师的办公室地址等信息。根据这些信息,我们可以设计一个课程表的数据表:
课程名 | 授课教师 | 办公室地址 |
---|---|---|
数据库原理 | 王老师 | 教学楼301 |
计算机组成原理 | 李老师 | 教学楼302 |
编译原理 | 张老师 | 教学楼303 |
在第一范式下,该表已经符合要求,因为每个属性都是原子的不可再分的基本数据项,并且每个属性都有唯一的属性名。
在第二范式下,我们需要根据课程名来进行排序,因此课程名成为了主键,该表符合第二范式的要求。
在第三范式下,我们需要判断授课教师和办公室地址之间是否存在冗余。如果授课教师的办公室地址是确定的,那么这张表就符合了第三范式的要求,但是实际上,我们并不能保证这一点。因此,我们需要对该表进行拆分:
教师信息表(Teacher):
教师名 | 办公室地址 |
---|---|
王老师 | 教学楼301 |
李老师 | 教学楼302 |
张老师 | 教学楼303 |
授课信息表(Course):
课程名 | 教师名 |
---|---|
数据库原理 | 王老师 |
计算机组成原理 | 李老师 |
编译原理 | 张老师 |
在第三范式下,教师信息表和授课信息表都不再存在冗余,符合了规范化设计的要求,并且可以有效降低数据冗余,提高查询效率。
到这里,我们对数据库规范化的基础知识和应用实例进行了详细的讲解,希望对读者有所帮助。