在数据库设计中,范式(Normal Forms) 是一种用于规范化数据库结构的设计原则,目的是减少数据冗余、提高数据一致性并避免更新异常。常见的范式包括:
- 第一范式(1NF)
- 第二范式(2NF)
- 第三范式(3NF)
- BC 范式(Boyce-Codd Normal Form, BCNF)
2NF
一个关系模式 R 属于 第二范式(2NF),当且仅当它满足以下两个条件:
完全依赖 vs 部分依赖
- 部分依赖(Partial Dependency):某个非主属性只依赖于候选键的一部分。
- 完全依赖(Full Dependency):非主属性必须依赖于整个候选键。
示例
假设有一个关系模式:
StudentEnroll(student_id, course_id, student_name, grade)
候选键是
(student_id, course_id)
,其中student_name
只依赖于student_id
,不依赖于course_id
→ 存在部分依赖。因此这个关系不是 2NF。需要将其拆分为:
- Student(student_id, student_name)
- Enroll(student_id, course_id, grade)
这样就符合 2NF 了。
指向原始笔记的链接
3NF
一个关系模式 R 属于 第三范式(3NF),当且仅当对于每一个 非平凡函数依赖 X → A,满足以下两个条件之一:
传递函数依赖
如果存在如下依赖链:
A → B,B → C,但 A ↛ C,
那么 C 对 A 是传递依赖。
示例
Employee(emp_id, name, dept_id, dept_name)
其中:
- emp_id → name, dept_id
- dept_id → dept_name
所以 emp_id → dept_name 是一个传递依赖,违反 3NF。
解决方法是将其拆分为:
- Employee(emp_id, name, dept_id)
- Department(dept_id, dept_name)
现在两个表都符合 3NF。
指向原始笔记的链接
BCNF
一个关系模式 R 属于 BCNF(Boyce-Codd Normal Form),当且仅当对于每一个非平凡的函数依赖 X → A:
X 必须是一个 超键(Superkey)
换句话说,只有当决定因素(X)是 候选键 时,才能有函数依赖。
特点
- BCNF 比 3NF 更严格。
- 在实际应用中,BCNF 能消除更多的更新异常。
- 不是所有关系都能分解为 BCNF 同时保持依赖(即可能无法做到既 BCNF 又保持所有函数依赖)。
示例
考虑关系:
CourseTeacher(course_id, teacher_id, office)
假设:
- course_id → teacher_id
- teacher_id → office
此时候选键是
course_id
,因为通过 course_id 可以唯一确定 teacher_id。但是
teacher_id → office
,而 teacher_id 并不是候选键,因此不符合 BCNF。解决方法是将其分解为:
- CourseTeacher(course_id, teacher_id)
- TeacherOffice(teacher_id, office)
这两个关系都满足 BCNF。
指向原始笔记的链接分解为 BCNF
将一个不属于 BCNF 的关系模式 R 分解为满足 BCNF 的形式,可以按照以下步骤进行:
- 找出一个违反 BCNF 的函数依赖(FD)X → Y。如果 X 不是 R 的 超键,且该函数依赖是非平凡的,则它违反了 BCNF。
- 在 R 所满足的所有函数依赖的集合下,计算 X 的 闭包(记作 )。
- 用两个新的关系模式替换 R:
- 第一个模式 R1,包含 中的所有属性。
- 第二个模式 R2,包含 R 中的所有属性,但去掉那些属于 但不属于 X 的属性。这可以表示为 。
- 将原始的函数依赖集分别投影到新的关系 R1 和 R2 上。
- 对 R1 和 R2 递归地应用上述分解过程,直到所有生成的关系模式都满足 BCNF。
这个过程确保了每个新关系要么已经满足 BCNF,要么可以进一步分解,直到满足 BCNF 的要求。
指向原始笔记的链接
范式 | 条件 | 解决的问题 |
---|---|---|
2NF | 消除对候选键的部分依赖 | 数据冗余、插入/删除异常 |
3NF | 消除非主属性对候选键的传递依赖 | 更进一步减少冗余 |
BCNF | 所有函数依赖的决定因素必须是候选键 | 最大程度消除更新异常 |