0%

数据库范式

一、理论讲解

数据库范式(Database Normalization)是组织数据库结构的一种方法,以减少数据冗余和提高数据完整性。范式是数据库设计的一组规则,分为不同的层次,每个层次解决特定类型的数据问题。主要的范式包括:

  1. **第一范式 (1NF)**:
    • 定义:表中的所有字段都应该是原子的,即不可再分的。
    • 要求:每个字段只包含一个值,消除重复的列。
    • 例子:如果一个表有一个字段用逗号分隔多个值,则不符合1NF。必须将这些值分解成独立的行或列。
  2. **第二范式 (2NF)**:
    • 定义:在满足1NF的基础上,消除部分依赖。
    • 要求:非主键字段必须完全依赖于主键,而不是依赖于主键的一部分(即消除部分依赖)。
    • 例子:如果一个表的主键由两个字段组成,而另一个字段只依赖于其中一个字段,则不符合2NF。需要将这些字段分解到不同的表中,使每个字段完全依赖于主键。
  3. **第三范式 (3NF)**:
    • 定义:在满足2NF的基础上,消除传递依赖。
    • 要求:非主键字段必须直接依赖于主键,而不能通过其他非主键字段间接依赖于主键(即消除传递依赖)。
    • 例子:如果一个表中有字段A依赖于主键,字段B依赖于字段A,则不符合3NF。需要将字段A和B分解到不同的表中,使每个字段直接依赖于主键。
  4. **巴斯-科德范式 (BCNF)**:
    • 定义:在满足3NF的基础上,处理更为严格的依赖关系。
    • 要求:每个非主键字段都必须完全依赖于候选键。
    • 例子:如果一个表中有多个候选键,而某个字段依赖于非主键的候选键,则需要进行进一步分解,确保所有字段都依赖于候选键。
  5. **第四范式 (4NF)**:
    • 定义:在满足BCNF的基础上,消除多值依赖。
    • 要求:每个字段必须依赖于主键,不允许存在多值依赖。
    • 例子:如果一个表中有一个字段依赖于另一个字段的多个值,则不符合4NF。需要将这些多值依赖的字段分解到不同的表中。
  6. **第五范式 (5NF)**:
    • 定义:在满足4NF的基础上,消除连接依赖。
    • 要求:所有的信息都应该可以通过原子表的自然连接来重构。
    • 例子:如果一个表中某些字段的组合信息依赖于另一个字段的组合信息,则不符合5NF。需要将这些字段进一步分解。

二、举例讲解

一个学校管理系统中的表,记录学生选课信息。初始表结构如下:

StudentID StudentName CourseID CourseName Instructor Grade
1 Alice 101 Math Dr. Smith A
1 Alice 102 English Dr. Brown B
2 Bob 101 Math Dr. Smith B
3 Charlie 103 History Dr. Green A

我们来一步步讲解各个范式,并规范化这个表。

第一范式 (1NF)

要求:所有字段都是原子的,不可再分。

初始表已经满足1NF,因为每个字段都包含单一值,不可再分。

第二范式 (2NF)

要求:在满足1NF的基础上,消除部分依赖。非主键字段必须完全依赖于主键,而不是依赖于主键的一部分。

当前表的主键是 StudentIDCourseID 的组合。但是:

  • StudentName 只依赖于 StudentID
  • CourseNameInstructor 只依赖于 CourseID

存在部分依赖,因此不满足2NF。我们需要将部分依赖的字段分解到不同的表中:

Students 表:

StudentID StudentName
1 Alice
2 Bob
3 Charlie

Courses 表:

CourseID CourseName Instructor
101 Math Dr. Smith
102 English Dr. Brown
103 History Dr. Green

Enrollments 表(存储学生选课和成绩信息):

StudentID CourseID Grade
1 101 A
1 102 B
2 101 B
3 103 A

现在每个表都满足2NF,因为所有非主键字段完全依赖于整个主键。

第三范式 (3NF)

要求:在满足2NF的基础上,消除传递依赖。非主键字段必须直接依赖于主键,而不能通过其他非主键字段间接依赖于主键。

假设我们在 Enrollments 表中添加了一个冗余字段 Instructor,表示授课教师:

StudentID CourseID Grade Instructor
1 101 A Dr. Smith
1 102 B Dr. Brown
2 101 B Dr. Smith
3 103 A Dr. Green

在这种情况下,Instructor 依赖于 CourseID,而 CourseID 是主键 StudentIDCourseID 的一部分。由于 Instructor 字段通过 CourseID 间接依赖于主键组合 StudentIDCourseID,这构成了传递依赖。因此,不满足3NF。

解决方法是移除 Instructor 字段,因为它可以从 Courses 表中得到:

StudentID CourseID Grade
1 101 A
1 102 B
2 101 B
3 103 A

巴斯-科德范式 (BCNF)

要求:在满足3NF的基础上,处理更为严格的依赖关系。每个非主键字段都必须完全依赖于候选键。

假设 Courses 表有以下结构:

CourseID CourseName Instructor RoomNumber
101 Math Dr. Smith 101
102 English Dr. Brown 102
103 History Dr. Green 103

如果 RoomNumber 依赖于 Instructor,则会违反BCNF。假设 Dr. Smith 总是在 Room 101 授课,那么 RoomNumber 应该依赖于 Instructor 而不是 CourseID

解决方法是分解 Courses 表:

Courses 表:

CourseID CourseName Instructor
101 Math Dr. Smith
102 English Dr. Brown
103 History Dr. Green

Instructors 表:

Instructor RoomNumber
Dr. Smith 101
Dr. Brown 102
Dr. Green 103

第四范式 (4NF)

要求:在满足BCNF的基础上,消除多值依赖。

假设我们有一个表记录学生的多种联系方式:

StudentID ContactType ContactValue
1 Email alice@example.com
1 Phone 123-456-7890
2 Email bob@example.com
2 Phone 098-765-4321

这里,ContactTypeContactValueStudentID 形成多值依赖。解决方法是分解成两个独立的表:

Emails 表:

StudentID Email
1 alice@example.com
2 bob@example.com

Phones 表:

StudentID Phone
1 123-456-7890
2 098-765-4321

第五范式 (5NF)

要求:在满足4NF的基础上,消除连接依赖。所有信息都应该可以通过原子表的自然连接来重构。

假设我们有一个表记录课程、教师和教材之间的关系:

CourseID Instructor Textbook
101 Dr. Smith Math Book
102 Dr. Brown English Book
103 Dr. Green History Book

假设每个课程可能有多个教师和多本教材,这样的关系会导致复杂的连接依赖。

解决方法是将关系分解为更小的表:

CourseInstructors 表:

CourseID Instructor
101 Dr. Smith
102 Dr. Brown
103 Dr. Green

CourseTextbooks 表:

CourseID Textbook
101 Math Book
102 English Book
103 History Book

InstructorTextbooks 表(仅在特定情况下需要,例如如果教材依赖于教师):

Instructor Textbook
Dr. Smith Math Book
Dr. Brown English Book
Dr. Green History Book

通过这些步骤,表结构满足了5NF。