数据库范式

范式

Normal form 简称NF

 

第一范式 1NF

原子性

一列中的数据不可在拆分,一个单元格只能存放一个单元数据

拆分非最小单元列

 

第二范式 2NF

满足1NF基础上

非主键列 依赖于 完全主键,不能只依赖一部分主键

例:

 

(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)

姓名和年龄不依赖于课程,即不完全依赖于主属性,因此不满足第二范式的要求,会产生如下问题:

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

拆分修改:

 

学生:Student(学号,姓名,年龄,性别,系别,系办地址、系办电话)
课程:Course(课程名称,学分)
选课关系:SelectCourse(学号,课程名称,成绩)

 

第三范式 3NF

满足2NF基础上

列直接依赖于主键,不可间接依赖、传递依赖

例:

 

(学号)→ (姓名,年龄,性别,系别,系办地址、系办电话)

还存在下面的决定关系:

 

(学号) → (系别)→(系办地点,系办电话)

即存在非关键字段"系办地点"、"系办电话"对关键字段"学号"的传递函数依赖。它也会存在数据冗余、更新异常、插入异常和删除异常的情况。

拆分修改:

 

学生:(学号,姓名,年龄,性别,系别);
系别:(系别,系办地址、系办电话)。

 

BCNF Boyce-Codd Normal Form(巴斯-科德范式)

满足3NF基础上

假设有如下条件:
某公司有若干个仓库;
每个仓库只能有一名管理员,一名管理员只能在一个仓库中工作;
一个仓库中可以存放多种物品,一种物品也可以存放在不同的仓库中。每种物品在每个仓库中都有对应的数量。
那么关系模式仓库(仓库名,管理员,物品名,数量) 属于哪一级范式?
已知:
函数依赖集:仓库名 → 管理员,管理员 → 仓库名,(仓库名,物品名)→ 数量
码:(管理员,物品名),(仓库名,物品名)
主属性:仓库名、管理员、物品名
非主属性:数量

因为不存在非主属性对码的部分函数依赖和传递函数依赖,所以此关系模式属于3NF。

既然此关系模式已经属于3NF,那么这个关系模式是否存在问题呢?
我们来看以下几种操作:

  • 先新增加一个仓库,但尚未存放任何物品,是否可以为该仓库指派管理员?——不可以,因为物品名也是主属性,根据实体完整性的要求,主属性不能为空。
  • 某仓库被清空后,需要删除所有与这个仓库相关的物品存放记录,会带来什么问题?——仓库本身与管理员的信息也被随之删除了。
  • 如果某仓库更换了管理员,会带来什么问题?——这个仓库有几条物品存放记录,就要修改多少次管理员信息。

从这里我们可以得出结论,在某些特殊情况下,即使关系模式符合3NF的要求,仍然存在着插入异常,修改异常与删除异常的问题,仍然不是"好"的设计。造成此问题的原因是存在着主属性对于码的部分函数依赖与传递函数依赖。(在此例中就是存在主属性【仓库名】对于码【(管理员,物品名)】的部分函数依赖。

解决方案:将表拆分成两个表,在3NF的基础上,消除主属性【仓库名】对于码【(管理员,物品名)】的部分与传递函数依赖。

将原来的仓库(仓库名,管理员,物品名,数量)
修改为:
仓库(仓库名,管理员)
库存(仓库名,物品名,数量)

这样,之前的插入异常,修改异常与删除异常的问题就被解决了。


参考:

数据库范式_百度百科

数据库六种范式详解(1NF/2NF/3NF/BCNF/4NF/5NF)_记忆碎片的博客-CSDN博客

posted @ 2021-11-15 22:11  RChang  阅读(49)  评论(0)    收藏  举报