关系数据库的范式是一系列规则,用于减少数据冗余,提升数据库设计的合理性和一致性。以下是主要范式的定义及例子:
第一范式 (1NF)
定义:所有属性都必须是原子性的(不可再分的)。即每一列中的数据都是不可分的单一值。
例子:考虑一个表 Orders
,包含如下数据:
OrderID | CustomerName | Items |
---|---|---|
1 | Alice | Pen, Pencil |
2 | Bob | Notebook |
在这个表中,Items
列包含多个商品,不符合1NF。为满足1NF,我们可以将 Items
分解,使每个单元格仅包含一个商品:
OrderID | CustomerName | Item |
---|---|---|
1 | Alice | Pen |
1 | Alice | Pencil |
2 | Bob | Notebook |
第二范式 (2NF)
定义:在满足第一范式的基础上,每个非主属性都必须完全依赖于主键,不能存在部分依赖。
例子:考虑一个 StudentCourses
表,其中主键是 (StudentID, CourseID):
StudentID | CourseID | StudentName | CourseName |
---|---|---|---|
1 | 101 | Alice | Math |
1 | 102 | Alice | Science |
2 | 101 | Bob | Math |
在该表中,StudentName
只依赖于 StudentID
,CourseName
只依赖于 CourseID
,这就导致了部分依赖,不符合2NF。
为满足2NF,我们可以分解表为两个表:
Students 表:
StudentID | StudentName |
---|---|
1 | Alice |
2 | Bob |
Courses 表:
CourseID | CourseName |
---|---|
101 | Math |
102 | Science |
StudentCourses 表:
StudentID | CourseID |
---|---|
1 | 101 |
1 | 102 |
2 | 101 |
第三范式 (3NF)
定义:在满足第二范式的基础上,每个非主属性都必须直接依赖于主键,不能存在传递依赖。
例子:考虑一个 Employees
表:
EmployeeID | DepartmentID | DepartmentName |
---|---|---|
1 | 10 | Sales |
2 | 20 | Marketing |
在此表中,DepartmentName
依赖于 DepartmentID
,而 DepartmentID
又依赖于 EmployeeID
,因此 DepartmentName
传递依赖于 EmployeeID
,不符合3NF。
为满足3NF,可以将 Department
相关信息分成一个单独的表:
Employees 表:
EmployeeID | DepartmentID |
---|---|
1 | 10 |
2 | 20 |
Departments 表:
DepartmentID | DepartmentName |
---|---|
10 | Sales |
20 | Marketing |
这样每个非主属性都直接依赖于主键,符合3NF。
BCNF (Boyce-Codd Normal Form)
定义:在满足3NF的基础上,所有非主属性必须完全依赖于候选键,适用于更复杂的候选键场景。
例子:考虑一个 ClassEnrollment
表,其中 (StudentID, CourseID) 是主键:
StudentID | CourseID | ProfessorID |
---|---|---|
1 | 101 | 1001 |
2 | 102 | 1002 |
假设 CourseID
决定 ProfessorID
,那么 ProfessorID
依赖于 CourseID
,而非主键组合 (StudentID, CourseID)。此时,我们可以将课程和教授信息分离:
Courses 表:
CourseID | ProfessorID |
---|---|
101 | 1001 |
102 | 1002 |
ClassEnrollment 表:
StudentID | CourseID |
---|---|
1 | 101 |
2 | 102 |
这样满足BCNF。