在数据库设计中,范式(Normal Forms) 是一种用于规范化数据库结构的设计原则,目的是减少数据冗余、提高数据一致性并避免更新异常。常见的范式包括:

  • 第一范式(1NF)
  • 第二范式(2NF)
  • 第三范式(3NF)
  • BC 范式(Boyce-Codd Normal Form, BCNF)

2NF

一个关系模式 R 属于 第二范式(2NF),当且仅当它满足以下两个条件:

  1. 已经属于 第一范式(1NF)(即每个属性都是原子的,不可再分)。
  2. 所有非 主属性完全函数依赖候选键(即不存在部分依赖)。

完全依赖 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 的形式,可以按照以下步骤进行:

  1. 找出一个违反 BCNF 的函数依赖(FD)X → Y。如果 X 不是 R 的 超键,且该函数依赖是非平凡的,则它违反了 BCNF。
  2. 在 R 所满足的所有函数依赖的集合下,计算 X 的 闭包(记作 )。
  3. 用两个新的关系模式替换 R:
    • 第一个模式 R1,包含 中的所有属性。
    • 第二个模式 R2,包含 R 中的所有属性,但去掉那些属于 但不属于 X 的属性。这可以表示为
  4. 将原始的函数依赖集分别投影到新的关系 R1 和 R2 上。
  5. 对 R1 和 R2 递归地应用上述分解过程,直到所有生成的关系模式都满足 BCNF。

这个过程确保了每个新关系要么已经满足 BCNF,要么可以进一步分解,直到满足 BCNF 的要求。

指向原始笔记的链接

指向原始笔记的链接

范式条件解决的问题
2NF消除对候选键的部分依赖数据冗余、插入/删除异常
3NF消除非主属性对候选键的传递依赖更进一步减少冗余
BCNF所有函数依赖的决定因素必须是候选键最大程度消除更新异常