数据库7种范式

在关系数据库设计中,存在多个范式,通常从第一范式(1NF)到更高阶的范式。以下是一些常见的数据库范式:

1. 第一范式(1NF)

确保每个表的每个列都包含原子值,不可再分。

  • 每个表都应该有一个主键:保证表中的每一行都是唯一标识的。
  • 表中的每一列都应该包含原子值:每个单元格中只能包含一个值,而不能包含多个值。

不满足第一范式的后果

  • 如果不符合第一范式,可能会导致数据冗余、更新异常和复杂的查询操作。

举例

违反第一范式的学生课程信息表:

学生ID 学生姓名 所修课程
1 小明 数学, 物理
2 小红 化学, 英语
3 小刚 生物, 历史, 地理

上述表违反了第一范式,因为 "所修课程" 这一列包含了多个值。正确的设计应该是将每门课程放在单独的行中:

学生ID 学生姓名 所修课程
1 小明 数学
1 小明 物理
2 小红 化学
2 小红 英语
3 小刚 生物
3 小刚 历史
3 小刚 地理

2. 第二范式(2NF)

确保表中的非主键列完全依赖于整个主键,而不是部分依赖。

也就是说2NF针对复合组件和部分依赖的情况。如果表中有一个复合组件(即有多个列组成的主键),那么所有其他非主键列都必须完全依赖于这个复合组件。

举例:

以下表格是一个具有复合主键(StudentID, CourseID)且存在冗余的表格。因为 CourseNameInstructor 不完全依赖于整个复合主键,而只依赖于部分主键。

StudentCourses
| StudentID | CourseID | CourseName | Instructor   |
|-----------|----------|------------|--------------|
| 1         | 101      | Math       | Prof. Smith  |
| 1         | 102      | English    | Prof. Johnson|
| 2         | 101      | Math       | Prof. Smith  |

冗余分析:

在原始表格中,Math和Prof. Smith的信息被重复存储了两次(两次在StudentID为1和2的行中出现),而这两门课实际上是相同的。这种冗余会导致以下问题:

1. 数据一致性:如果对MathProf. Smith的信息进行修改,需要在多个地方进行更新,容易出现数据不一致的情况。

2. 存储空间浪费: 存储相同的课程信息多次会浪费存储空间,尤其在大型数据库中可能成为一个问题。

3. 维护复杂性: 数据冗余增加了维护的复杂性,因为需要确保多个地方的数据保持一致。

通过拆分表格,我们可以消除这些冗余,如拆分后的Courses表格所示:

Students
| StudentID | StudentName |
|-----------|-------------|
| 1         | John        |
| 2         | Jane        |

Courses
| CourseID | CourseName | Instructor   |
|----------|------------|--------------|
| 101      | Math       | Prof. Smith  |
| 102      | English    | Prof. Johnson|

StudentCourses
| StudentID | CourseID |
|-----------|----------|
| 1         | 101      |
| 1         | 102      |
| 2         | 101      |

现在,每门课程只有一条记录,避免了在原表格中重复存储相同的课程信息。这有助于提高数据一致性、减少存储空间的浪费,并简化了维护过程。这就是通过第二范式的原则来消除冗余的方式。

3. 第三范式(3NF)

确保表中的每个非主键列不依赖于其他非主键列,即不存在传递依赖

  • 影响一致性: 3NF 要求表中的非主键列不能有传递依赖关系,进一步确保了数据的一致性。每个非主键列都直接依赖于主键,而不是依赖于其他非主键列。
  • 减少冗余: 3NF 通过消除非主键列之间的传递依赖,减少了数据冗余。

举例:

考虑一个包含学生信息、课程信息和学生成绩的表格:

在上述表格中,(StudentID, CourseID) 是复合主键。这个表格满足第二范式,因为非主键列(例如 InstructorDepartment)完全依赖于整个复合主键, 只有一个完整的(StudentID, CourseID)才能确定一个Instructor 或者Department  。然而,该表不满足第三范式,因为 Instructor 和Department列直接依赖于 CourseID,而 CourseID 又依赖于 StudentID。存在传递依赖关系,违反了第三范式的要求。

StudentCourses
| StudentID | CourseID | Instructor   | Department   |
|-----------|----------|--------------|--------------|
| 1         | 101      | Prof. Smith  | Computer Sci |
| 1         | 102      | Prof. Johnson| English      |
| 2         | 101      | Prof. Smith  | Computer Sci |

为了满足第三范式,我们可以将表格拆分,将 Instructor 列从 StudentCourses 表中分离:

1. Courses

Courses
| CourseID | Department   |
|----------|--------------|
| 101      | Computer Sci |
| 102      | English      |

2. StudentCourses

StudentCourses
| StudentID | CourseID |
|-----------|----------|
| 1         | 101      |
| 1         | 102      |
| 2         | 101      |

3. Instructors

Instructors
| CourseID | Instructor   |
|----------|--------------|
| 101      | Prof. Smith  |
| 102      | Prof. Johnson|

4. 巴斯-科德规范形式(BCNF)

也就是说对表格里的每一个候选键,当他们作为主键时,每个非主属性都要完全依赖于该候选键,才算满足BCNF范式。候选键是可以唯一标识一行数据的最小组合。

  • 主要关注消除关系中的部分依赖和传递依赖
  • 要求每个非主属性完全依赖于候选键,而不是只依赖于候选键的一部分。
  • 通过分解表来消除部分依赖和传递依赖的影响,确保每个非主属性都直接依赖于所有的候选键。

示例:

Orders
| OrderID | ProductID | ProductName | CustomerID | CustomerName | Price |
|---------|-----------|-------------|------------|--------------|-------|
| 1       | 101       | Laptop      | 1001       | John         | 1200  |
| 2       | 102       | Printer     | 1002       | Jane         | 300   |
| 3       | 101       | Laptop      | 1003       | Bob          | 1200  |

在上述表格中,(OrderID, ProductID) 是候选键。但是,CustomerName 仅依赖于 CustomerID,而不依赖于整个候选键。为了满足 BCNF,可以将表格拆分:

Orders
| OrderID | ProductID | CustomerID | Price |
|---------|-----------|------------|-------|
| 1       | 101       | 1001       | 1200  |
| 2       | 102       | 1002       | 300   |
| 3       | 101       | 1003       | 1200  |

Customers
| CustomerID | CustomerName |
|------------|--------------|
| 1001       | John         |
| 1002       | Jane         |
| 1003       | Bob          |

5. 第四范式(4NF)

处理多值依赖,确保每个非主键属性完全依赖于候选键,而不是依赖于候选键的一部分。

  • 主要关注消除关系中的多值依赖
  • 多值依赖是指在关系中的非主属性之间存在的关系,其中一个非主属性的值可以决定另一个非主属性的值。
  • 通过分解表来消除多值依赖,确保表中的每个非主属性都不依赖于其他非主属性的非主属性。

示例:

考虑一个表格 Employees

Employees
| EmployeeID | Department   | Skills            |
|------------|--------------|-------------------|
| 1          | HR           | Communication, HR|
| 2          | IT           | Programming, IT   |
| 3          | Marketing    | Marketing, Sales  |

在上述表格中,Skills 列包含多个值,表示一个员工可能有多个技能。为了满足第四范式,可以将表格拆分:

Employees
| EmployeeID | Department |
|------------|------------|
| 1          | HR         |
| 2          | IT         |
| 3          | Marketing  |

EmployeeSkills
| EmployeeID | Skill        |
|------------|--------------|
| 1          | Communication|
| 1          | HR           |
| 2          | Programming  |
| 2          | IT           |
| 3          | Marketing    |
| 3          | Sales        |

6. 第五范式(5NF)

处理联合依赖,确保每个非主键属性不依赖于候选键的某一部分。

示例:

考虑一个包含项目、部门和员工信息的表格:

Projects
| ProjectID | ProjectName | DepartmentID | DepartmentName | EmployeeID | EmployeeName |
|-----------|-------------|--------------|-----------------|------------|--------------|
| 1         | ProjectA    | 101          | HR              | 1001       | John         |
| 2         | ProjectB    | 102          | IT              | 1002       | Jane         |
| 3         | ProjectC    | 103          | Marketing       | 1003       | Bob          |

在上述表格中,(ProjectID, DepartmentID) 是联合主键。如果考虑 (ProjectID, DepartmentID) -> EmployeeID 的联合依赖关系,那么我们可以将表格拆分

Projects
| ProjectID | ProjectName | DepartmentID |
|-----------|-------------|--------------|
| 1         | ProjectA    | 101          |
| 2         | ProjectB    | 102          |
| 3         | ProjectC    | 103          |

Departments
| DepartmentID | DepartmentName |
|--------------|-----------------|
| 101          | HR              |
| 102          | IT              |
| 103          | Marketing       |

Employees
| EmployeeID | EmployeeName |
|------------|--------------|
| 1001       | John         |
| 1002       | Jane         |
| 1003       | Bob          |

ProjectEmployees
| ProjectID | DepartmentID | EmployeeID |
|-----------|--------------|------------|
| 1         | 101          | 1001       |
| 2         | 102          | 1002       |
| 3         | 103          | 1003       |

这样,联合依赖关系被消除,每个表都只包含必要的信息。

7. 第六范式(6NF)

处理超关系(超关系是一个关系中的某些属性是另一个关系的关系键)。

是关系数据库理论中的一个较为高级和少用的范式。它主要涉及到多值依赖的概念,通常在包含多值依赖的情况下才会考虑使用。

示例:

考虑一个包含课程、学生和成绩的表格:

Grades
| CourseID | StudentID | Grade |
|----------|-----------|-------|
| 101      | 1001      | A     |
| 102      | 1002      | B     |
| 101      | 1003      | C     |

在上述表格中,(CourseID, StudentID) 是联合主键。如果考虑 CourseID -> Grade 的函数依赖关系,我们可以将表格拆分:

Courses
| CourseID | CourseName |
|----------|------------|
| 101      | Math       |
| 102      | English    |

Students
| StudentID | StudentName |
|-----------|-------------|
| 1001      | John        |
| 1002      | Jane        |
| 1003      | Bob         |

CourseGrades
| CourseID | Grade |
|----------|-------|
| 101      | A     |
| 102      | B     |
| 101      | C     |

StudentCourseGrades
| StudentID | CourseID | Grade |
|-----------|----------|-------|
| 1001      | 101      | A     |
| 1002      | 102      | B     |
| 1003      | 101      | C     |

8. 第七范式(7NF)

第七范式通常涉及到更复杂的概念,主要用于处理多值依赖。在实际应用中,很少需要考虑到第七范式,因为这个范式要求的条件非常严格,而且可能导致过多的表和复杂的查询。

你可能感兴趣的:(数据库,数据结构,大数据,sql,开发语言,算法,python)