第五章:如何理解关系数据的范式

1、引言

        关系数据库的范式(Normalization)是数据库设计中的一种规范化过程,旨在通过一系列规则来优化数据库表结构,以减少数据冗余、提高数据完整性和一致性。

1.1 范式的核心思想

        范式的核心思想是确保数据库中的每个数据项都存储在适当的位置,并且每个数据项都只有一个明确的、无冗余的存储位置。这有助于避免数据重复、插入异常、删除异常和更新异常等问题。

1.2 范式的目标

范式的主要目标包括:

  • 减少数据冗余:避免重复存储相同的数据。

  • 提高数据一致性:确保数据在不同表中的一致性。

  • 简化数据维护:使数据的插入、更新和删除操作更加高效。

  • 优化查询性能:通过合理的表结构设计,提高查询效率。

1.3 范式的层次与要求

        关系数据库的范式通常分为六个层次,从第一范式(1NF)到第五范式(5NF,又称完美范式),每个层次都提出了更严格的要求:

  1. 第一范式(1NF):要求数据库表中的每个字段都是原子的,即不可再分的。这是数据库规范化的基础。

  2. 第二范式(2NF):在满足第一范式的基础上,要求数据库表中的每个非主键字段都完全依赖于主键。这有助于消除部分依赖,减少数据冗余。

  3. 第三范式(3NF):在满足第二范式的基础上,要求数据库表中的每个非主键字段都不传递依赖于主键。这有助于消除传递依赖,进一步提高数据完整性。

  4. 巴斯-科德范式(BCNF):是对第三范式的修正,要求所有非主键字段都完全依赖于候选键(可能是主键或主键的一部分),并且每个非主键字段都不能对候选键的子集产生依赖。这有助于进一步减少数据冗余和更新异常。

  5. 第四范式(4NF):在满足BCNF的基础上,要求消除多值依赖。多值依赖是指一个字段的值可能对应多个其他字段的值,这会导致数据冗余和复杂性增加。通过消除多值依赖,可以使数据库结构更加清晰和高效。

  6. 第五范式(5NF,又称完美范式):是对第四范式的进一步扩展,要求消除连接依赖。连接依赖是指一个表中的字段可能依赖于另一个表中的字段,这会导致数据冗余和复杂性增加。通过消除连接依赖,可以使数据库结构更加简洁和高效,提高数据访问性能。

1.4  6范式及其关系

1.5 6范式对比

1.6 概念说明

  • 关系(Rrelation):关系是一个二维表格,由行和列组成。每一行称为一个元组(Tuple),每一列称为属性(Attribute)。
  • 元组(Tuple):元组是关系中的一条记录,包含了该记录的所有属性值。
  • 属性(attribute):数据库中的字段,即数据库中表的列。
  • 超键(super key):在关系中能唯⼀标识元组的属性集称为关系模式的超键。
  • 候选键(candidate key):不含有多余属性的超键称为候选键。
  • 主键(primary key):⽤户选作元组标识的⼀个候选键称为主键
  • 外键(foreign key):在一个表中存在的另一个表的主键称为此表的外键。
  • 主属性:候选键中的属性称为主属性。
  • 非主属性:不属于任何候选键的属性称为非主属性。

2 第一范式(1NF)

2.1 定义

        表中的每一列都是不可再分的原子值,即每一列都是单一值,不能包含集合、数组或重复组。

        简言之:无重复的列(确保每列保持原子性)。

2.2 要求

  1. 每个属性都是原子性的,即属性的值必须是不可再分的基本数据项。
  2. 每个属性都具有唯一的名称,不能重复。
  3. 每个属性只能包含单一的数据类型,例如字符、数字、日期等。
  4. 每个记录都必须具有唯一的标识,即主键。

2.3 作用

        确保每个字段保持原子性,不可再分,从而避免数据冗余和不一致。

2.4 示例

  • 不符合 1NF 的表

    Student_ID Name Courses
    101 John Doe Math, Science
    102 Jane Smith History, English
  • 符合 1NF 的表

    Student_ID Name Course
    101 John Doe Math
    101 John Doe Science
    102 Jane Smith History
    102 Jane Smith English

2.5 特点

  • 每一列都是原子的。

  • 没有重复组。

3 第二范式(2NF)

3.1 定义

        在满足 1NF 的基础上,表中的每一列都必须完全依赖于主键,而不是部分依赖。

        简言之:属性完全依赖于主键(消除部分子函数依赖,确保表中的每列都和主键相关)。

3.2 要求

  1. 满足第一范式。
  2. 非主属性必须完全依赖于候选键,不能存在部分依赖。
  3. 为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。

3.3 作用

        消除部分依赖,进一步减少数据冗余。

3.4 示例

  • 不符合 2NF 的表

    Order_ID Product_ID Product_Name Quantity
    1 101 Laptop 2
    1 102 Mouse 5
    • Product_Name 依赖于 Product_ID,而不是完全依赖于主键 (Order_ID, Product_ID)

  • 不符合第二范式,会出现的问题:

        (1) 数据冗余:同一个客户下的订单,所属单位和联系方式出现了冗余
        (2) 更新异常:如果调整了某个商品的价格,表中所有下单该商品的价格表都需要调整,否则会出现同一商品价格不统一的情况
        (3) 插入异常:如果商家新增了一个商品,由于还没有人买过没有订单号,导致表中无法插入这样的信息信息了
        (4) 删除异常:如果客户已完成订单,或者客户退货取消订单,就需要删除订单编号,这样又会导致商品信息被删除,问题更大了。

  • 符合 2NF 的表

    • 表 1:订单详情

      Order_ID Product_ID Quantity
      1 101 2
      1 102 5
    • 表 2:产品信息

      Product_ID Product_Name
      101 Laptop
      102 Mouse

        这样设计,在很大程度上减小了数据库的冗余。

3.5 特点

  • 消除部分依赖。

  • 将表拆分为多个表,确保非主键列完全依赖于主键。

4 第三范式(3NF)

4.1 定义

        在满足 2NF 的基础上,表中的每一列都不能传递依赖于主键,即非主键列之间不能有依赖关系。

       简言之:属性不依赖于其它非主属性(消除传递依赖,确保每列都和主键列直接相关,而不是间接相关)。        

4.2 要求

  1. 满足第二范式。
  2. 非主属性不能传递依赖于候选键,即一个非主属性不能依赖于另一个非主属性。
  3. 所谓传递函数依赖,指的是如果存在"A → B → C"的决定关系,则C传递函数依赖于A。

4.3 作用

        消除传递依赖,进一步减少数据冗余,提高数据完整性。

4.4 示例

  • 不符合 3NF 的表

    Employee_ID Name Department_ID Department_Name
    101 John 1 HR
    102 Jane 2 Finance
    • Department_Name 依赖于 Department_ID,而 Department_ID 依赖于 Employee_ID,存在传递依赖。

  • 符合 3NF 的表

    • 表 1:员工信息

      Employee_ID Name Department_ID
      101 John 1
      102 Jane 2
    • 表 2:部门信息

      Department_ID Department_Name
      1 HR
      2 Finance

4.5 特点

  • 消除传递依赖。

  • 将表进一步拆分,确保非主键列只依赖于主键。

5 更高范式

5.1 巴斯-科德范式(BCNF)

5.1.1 定义

        在满足 3NF 的基础上,进一步消除主键列之间的依赖关系,确保每个依赖的左部都是候选键。

        简言之:消除主属性对于候选键的部分函数依赖和传递函数依赖。

5.1.2 要求

  1. 满足第三范式。
  2. 所有属性都完全依赖于候选键,包括主属性。
  3. 主属性不能对主键子集依赖。

5.1.3 作用

        修正第三范式中的不足,进一步减少数据冗余,提高数据库性能。

5.1.4 示例

  • 不符合 BCNF 的表

    Student_ID Course_ID Instructor_ID
    101 Math 1
    102 Science 2
    • 假设每个课程只有一个教师,Instructor_ID 依赖于 Course_ID,但 Course_ID 不是候选键。

  • 符合 BCNF 的表

    • 表 1:学生选课

      Student_ID Course_ID
      101 Math
      102 Science
    • 表 2:课程教师

      Course_ID Instructor_ID
      Math 1
      Science 2

5.1.5 特点

  • 消除主键列之间的依赖。

  • 确保每个依赖的左部都是候选键。

5.2第四范式(4NF)

5.2.1 定义

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

        简言之:消除属性间非平凡且非函数依赖的多值依赖。

5.2.2 要求

  1. 满足BCNF。
  2. 消除多值依赖,即一个属性不能对应多个值,除非这些值被明确地表示为另一个表的外键。
  3. 当一个表中的非主属性互相独立时(3NF),这些非主属性不应该有多值。若有多值就违反了第四范式。

5.2.3 作用

        消除多值依赖,使数据库结构更加清晰,减少数据冗余和复杂性。

5.2.4 示例

  • 不符合 4NF 的表

    Student_ID Course Hobby
    101 Math Reading
    101 Science Reading
    101 Math Sports
    101 Science Sports
    • Course 和 Hobby 是多值依赖。

  • 符合 4NF 的表

    • 表 1:学生课程

      Student_ID Course
      101 Math
      101 Science
    • 表 2:学生爱好

      Student_ID Hobby
      101 Reading
      101 Sports

5.2.5 特点

  • 消除多值依赖。

  • 将表拆分为多个表,确保每个表只包含单值依赖。

5.3 第五范式(5NF,又称完美范式)

5.3.1 定义

       在满足 4NF 的基础上,消除连接依赖,确保表可以无损分解为更小的表。

        简言之:消除关系中的所有冗余。

5.3.2 要求

  1. 满足第四范式。
  2. 表必须可以分解为较小的表,除非那些表在逻辑上拥有与原始表相同的主键。

5.3.3 作用

        消除连接依赖,使数据库结构更加简洁和高效,提高数据访问性能。第五范式是在第四范式的基础上做的进一步规范化。第四范式处理的是相互独立的多值情况,而第五范式则处理相互依赖的多值情况。

5.3.4 示例

  • 不符合 5NF 的表

    Student_ID Course Instructor
    101 Math John
    101 Science Jane
    • 如果 Student_ID 和 CourseCourse 和 InstructorStudent_ID 和 Instructor 之间存在独立的依赖关系。

  • 符合 5NF 的表

    • 表 1:学生课程

      Student_ID Course
      101 Math
      101 Science
    • 表 2:课程教师

      Course Instructor
      Math John
      Science Jane
    • 表 3:学生教师

      Student_ID Instructor
      101 John
      101 Jane

5.3.5  特点

  • 消除连接依赖。

  • 确保表可以无损分解。

6 总结

        关系数据库的六范式是数据库设计中非常重要的规则,它们共同构成了数据库规范化的基础。通过遵循这些范式,可以设计出结构清晰、数据冗余少、完整性高的数据库表结构,从而提高数据库的性能和可靠性。在实际应用中,可以根据具体需求和数据库特点灵活选择和应用这些范式。

        通常来说,数据库只需满足前第三范式(3NF)就足够了。