关系范式

写在前面

1NF

定义:如果数据表的所有属性都是 不可分 的基本数据项,则符合 1NF。

数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。

不满足第一范式就不是关系型数据库!

很显然,在当前的任何关系数据库管理系统(RDBMS,Relational Database Management System)中,天才也不能做出不符合第一范式的数据库。因为这些 RDBMS 不允许你把数据库表的一列再分成二列乃至多列,所以想在现有的 RDBMS 中设计出不符合第一范式的数据库是不可能的。

2NF

  • 定义:在 1NF 的基础上,数据表每一个非主属性都 完全函数依赖 于主属性,则符合 2NF。
  • 解释:

    • 表中的属性必须依赖于全部主键,而不是部分主键,也即转化为 2NF 就是消除属性对主属性的部分依赖。
    • 另外,所有单关键字的数据库表都符合 2NF,因为不可能存在组合关键字。
  • 案例:选课关系表 SelectCourse (学号, 姓名, 年龄, 课程名称, 成绩, 学分),关键字为组合关键字 (学号, 课程名称)。
  • 分析:这个数据库表符合 1NF 的,但是不符合 2NF。

    • 因为存在如下决定关系:(课程名称) → (学分);(学号) → (姓名, 年龄)。存在非主属性部分依赖于主属性,或者说存在主关键字中的字段决定非关键字的情况。
  • 异常情况:由于不符合 2NF,这个 SelectCourse 会存在如下问题:

    • 数据冗余:同一门课程由 n 个学生选修,学分 就重复 n - 1 次;同一个学生选修了 m 门课程,姓名年龄 就重复了 m - 1 次。
    • 更新异常:若调整了某门课程的学分,表中所有对应 课程名称 元组的 学分 属性都要同步更新,否则会出现同一门课程学分不同的情况。
    • 插入异常:假设要开设一门新的课程,暂时还没有人选修。由于还没有 学号 关键字,课程名称学分 也无法记录入数据库。
    • 删除异常:假设一批学生已经完成课程的选修,这些选修记录就应该从表中删除。但是与此同时 课程名称学分 信息也被删除了。很显然这也会导致插入异常。
  • 改造:

    • SelectCourse 改为如下三个表:

      • 学生:Student (学号, 姓名, 年龄)
      • 课程:Course (课程名称, 学分)
      • 选课关系:SelectCourse (学号, 课程名称, 成绩)
    • 这样的数据库表是符合 2NF 的,消除了数据冗余、更新异常、插入异常和删除异常。

3NF

  • 定义:在 2NF 的基础上,数据表中如果不存在非关键字段对任一候选关键字段的 传递函数依赖 则符合 3NF。
  • 案例:学生关系表 Student (学号, 姓名, 年龄, 所在学院, 学院地点, 学院电话),关键字为单一关键字 学号
  • 分析:这个数据库表是符合 2NF 的,但是不符合 3NF。

    • 因为存在如下决定关系: (学号) → (所在学院) → (学院地点, 学院电话)。即存在非关键字段 学院地点学院电话 对关键字段 学号 的传递函数依赖。
  • 异常情况:存在数据冗余、更新异常、插入异常和删除异常的情况。

    • 数据冗余:同一个院校有 n 个学生,那么 学院地点学院电话 就重复存储了 n-1 次。
    • 更新异常:若更改了某个学院的地点,表中所有对应 所在学院 元组的 学院地点 属性都要同步更新,否则就会出现不一致的情况。
    • 插入异常:如果某个新的学院里没有学生,那么就无法将该学院插入数据库。
    • 删除异常:如果删除了一个学院的所有学生,那么该学院也将被删除掉。
  • 改造:

    • Student 分为如下两个表:

      • 学生:Student (学号, 姓名, 年龄, 所在学院)
      • 学院:College (学院, 地点, 电话)
    • 这样的数据库表是符合 3NF 的,消除了数据冗余、更新异常、插入异常和删除异常。

BCNF

  • 定义:在 3NF 的基础上,数据库表中如果 不存在任何字段 对任一候选关键字段的传递函数依赖则符合 BCNF。
  • 解释:3NF 已经消除了非关键字段对任一候选关键字段的传递函数依赖,那么到 BCNF 就只需要消除 候选关键字段之间 的传递函数依赖即可。
  • 案例:

    • 仓库管理关系表 StorehouseManage (仓库 ID, 存储物品 ID, 管理员 ID, 数量),且有一个管理员只在一个仓库工作;一个仓库可以存储多种物品。
  • 分析:这个数据库表是符合 3NF 的,但是不符合 BCNF。

    • 这个数据库表中存在如下决定关系:

      • (仓库 ID, 存储物品 ID) → (管理员 ID, 数量)
      • (管理员 ID, 存储物品 ID) → (仓库 ID, 数量)
    • 所以 (仓库 ID, 存储物品 ID) 和 (管理员 ID, 存储物品 ID) 都是 StorehouseManage 的候选关键字,表中的唯一非关键字段为 数量,它是符合 3NF 的。
    • 但是由于存在如下决定关系:

      • (仓库 ID) → (管理员 ID)
      • (管理员 ID) → (仓库 ID)
    • 即存在关键字段决定关键字段的情况,所以其不符合 BCNF。
  • 异常情况:存在数据冗余、更新异常、插入异常和删除异常的情况。

    • 数据冗余:一个仓库存储 n 种物品,则 仓库 ID管理员 ID 重复存储了 n - 1 次。
    • 更新异常:如果仓库换了管理员,则所有对应 仓库 ID 元组的 管理员 ID 属性都要同步更新,否则出现数据不一致。
    • 插入异常:如果新建了一个仓库,但是它没有存储物资,那么就无法插入数据库。
    • 删除异常:如果一个仓库下存储的物资都被删除了,那么仓库也将被删除掉。
  • 改造:

    • StorehouseManage 分解为两个关系表:

      • 仓库管理:StorehouseManage (仓库 ID, 管理员 ID)
      • 仓库:Storehouse (仓库 ID, 存储物品 ID, 数量)
    • 这样的数据库表是符合 BCNF 的,消除了删除异常、插入异常和更新异常。
  • 再举一例:表 (学生, 教师, 课程),规定每位教师只开一门课,那么存在如下决定关系:

    • (学生, 教师) → U (学生, 教师, 课程)
    • (学生, 课程) → U (学生, 教师, 课程)
    • 教师课程
    • 课程教师
    • 存在关键字段决定关键字段的情况,所以不符合 BCNF。
最后修改:2022 年 12 月 02 日
如果觉得我的文章对你有用,请随意赞赏