范式复习
1NF、2NF、3NF和4NF是数据库设计中用于消除数据冗余和提高数据完整性的规范化形式。这些规范化形式基于一组规则,指导数据库中的数据组织过程。
1. 第一范式(1NF):
第一范式要求数据库表具有主键,并且每个列仅包含原子值(不可分割的值)。它消除了重复的数据组,并确保每个列具有单个值。
2. 第二范式(2NF):
第二范式在1NF的基础上进行了扩展。它规定数据库表必须符合1NF,并且所有非关键属性(列)必须完全依赖于整个主键。换句话说,它通过将部分依赖关系移至单独的表中来消除部分依赖。
3. 第三范式(3NF):
第三范式在2NF的基础上进行了扩展。它规定数据库表必须符合2NF,并且所有非关键属性(列)只能依赖于主键,而不能依赖于其他非关键属性。它通过将传递依赖关系移至单独的表中来消除传递依赖。
4. 第四范式(4NF):
第四范式在3NF的基础上进行了扩展。它规定数据库表必须符合3NF,并且不应具有多值依赖关系。换句话说,它消除了非关键属性依赖于其他非关键属性组合的情况。
每个更高的范式都包含了前一个范式的要求。范式越高,数据库设计就越规范化,冗余就越少。但是,实现更高的范式可能涉及到复杂性增加和性能考虑的权衡。在设计数据库模式时,平衡规范化和实际应用需求非常重要。
举个例子,假设我们有一个学生课程数据库,其中包含以下两个表:
学生表(Student):
| 学生ID(StudentID) | 学生姓名(StudentName) | 年级(Grade) |
|-------------------|----------------------|--------------|
| 1 | 张三 | 10 |
| 2 | 李四 | 11 |
课程表(Course):
| 课程ID(CourseID) | 课程名称(CourseName) | 学生ID(StudentID) |
|------------------|---------------------|------------------|
| 1 | 数学 | 1 |
| 2 | 英语 | 1 |
| 3 | 历史 | 2 |
在1NF中,每个表都有唯一的主键(StudentID和CourseID),并且每个列都包含原子值,没有重复的数据组。
在2NF中,我们可以将学生表分解为两个表:学生表(Student)和年级表(Grade),其中学生表的非关键属性完全依赖于主键(StudentID),而年级表则与主键无关。这样可以消除部分依赖。
学生表(Student):
| 学生ID(StudentID) | 学生姓名(StudentName) |
|-------------------|----------------------|
| 1 | 张三 |
| 2 | 李四 |
年级表(Grade):
| 学生ID(StudentID) | 年级(Grade) |
|------------------|--------------|
| 1 | 10 |
| 2 | 11 |
课程表(Course)仍然保持不变,因为它的非关键属性(课程名称)已经完全依赖于主键(CourseID)。
在3NF中,我们进一步分解课程表,以消除传递依赖。我们将课程表分解为课程表(Course)和学生课程关系表(StudentCourse):
课程表(Course):
| 课程ID(CourseID) | 课程名称(CourseName) |
|------------------|---------------------|
| 1 | 数学 |
| 2 | 英语 |
| 3 | 历史 |
学生课程关系表(StudentCourse):
| 学生ID(StudentID) | 课程ID(CourseID) |
|------------------|------------------|
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
现在,课程表的非关键属性(课程名称)仅依赖于主键(CourseID),而不依赖于其他非关键属性。这样消除了传递依赖。
最后,在4NF中,我们需要检查是否存在多值依赖。在上述示例中,并不存在多值依赖的情况,因此不需要进一步分解。
通过按照这些规范化形式逐步优化数据库设计,我们可以消除冗余数据,提高数据完整性,并使数据库结构更加规范化。



在这个例子中,学生姓名和课程名称的非关键属性传递依赖于学生ID和课程ID的联合主键。
为了将其转换为3NF,我们需要将传递依赖关系消除,创建一个新的教师表(Teacher)来分离教师姓名和教师ID。
操作步骤如下:
1. 创建一个新的教师表(Teacher),其中包含教师ID和教师姓名。
教师表(Teacher):
| 教师ID(TeacherID) | 教师姓名(TeacherName) |
|------------------|---------------------|
| 1 | 王老师 |
| 2 | 李老师 |
2. 更新学生课程教师表(StudentCourseTeacher),移除非关键属性(学生姓名、课程名称)中的传递依赖。
学生课程教师表(StudentCourseTeacher):
| 学生ID(StudentID) | 课程ID(CourseID) | 教师ID(TeacherID) | 成绩(Grade) |
|-------------------|------------------|------------------|--------------|
| 1 | 1 | 1 | 80 |
| 1 | 2 | 2 | 85 |
| 2 | 1 | 1 | 90 |
现在,学生课程教师表(StudentCourseTeacher)中的非关键属性不再传递依赖于联合主键,传递依赖关系已经被消除。
通过以上操作,我们将学生课程表从1NF转换为2NF,将学生课程教师表从2NF转换为3NF,分别消除了部分依赖和传递依赖关系。这样可以提高数据库的规范性和数据完整性。