数据库1NF 2NF 3NF范式解释


定义

范式(NF)”是什么意思。按照教材中的定义,范式是“符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度”。
数据库范式也分为1NF,2NF,3NF,BCNF,4NF,5NF。一般在我们设计关系型数据库的时候,最多考虑到BCNF就够。符合高一级范式的设计,必定符合低一级范式,例如符合2NF的关系模式,必定符合1NF。


第一范式

符合1NF的关系(你可以理解为数据表。“关系”和“关系模式”的区别,类似于面向对象程序设计中”类“与”对象“的区别。”关系“是”关系模式“的一个实例,你可以把”关系”理解为一张带数据的表,而“关系模式”是这张数据表的表结构。1NF的定义为:符合1NF的关系中的每个属性都不可再分。
(表1所示的情况,就不符合1NF的要求。)

表一
实际上,1NF是所有关系型数据库的最基本要求,你在关系型数据库管理系统(RDBMS),例如SQL Server,Oracle,MySQL中创建数据表的时候,如果数据表的设计不符合这个最基本的要求,那么操作一定是不能成功的。也就是说,只要在RDBMS中已经存在的数据表,一定是符合1NF的。如果我们要在RDBMS中表现表中的数据,就得设计为表2的形式:

表二
但是仅仅符合1NF的设计,仍然会存在数据冗余过大,插入异常,删除异常,修改异常的问题
例如对于表3中的设计:

表三

1.每一名学生的学号、姓名、系名、系主任这些数据重复多次。每个系与对应的系主任的数据也重复多次——数据冗余过大
2.假如学校新建了一个系,但是暂时还没有招收任何学生(比如3月份就新建了,但要等到8月份才招生),那么是无法将系名与系主任的数据单独地添加到数据表中去的 (注1)——插入异常

* 注1:根据三种关系完整性约束中实体完整性的要求,关系中的码(注2)所包含的任意一个属性都不能为空,所有属性的组合也不能重复。为了满足此要求,图中的表,只能将学号与课名的组合作为码,否则就无法唯一地区分每一条记录。

*注2:码:关系中的某个属性或者某几个属性的组合,用于区分每个元组(可以把“元组”理解为一张表中的每条记录,也就是每一行)。

3.假如将某个系中所有学生相关的记录都删除,那么所有系与系主任的数据也就随之消失了(一个系所有学生都没有了,并不表示这个系就没有了)。——删除异常
4.假如李小明转系到法律系,那么为了保证数据库中数据的一致性,需要修改三条记录中系与系主任的数据。——修改异常。

正因为仅符合1NF的数据库设计存在着这样那样的问题,我们需要提高设计标准,去掉导致上述四种问题的因素,使其符合更高一级的范式(2NF),这就是所谓的“规范化”。


第二范式

在关系理论中的严格定义我这里就不多介绍了(因为涉及到的铺垫比较多),只需要了解2NF对1NF进行了哪些改进即可。其改进是,2NF在1NF的基础之上,消除了非主属性对于码的部分函数依赖。接下来对这句话中涉及到的四个概念——“函数依赖”、“码”、“非主属性”、与“部分函数依赖”进行一下解释。

函数依赖
我们可以这么理解(但并不是特别严格的定义):若在一张表中,在属性(或属性组)X的值确定的情况下,必定能确定属性Y的值,那么就可以说Y函数依赖于X,写作 X → Y。也就是说,在数据表中,不存在任意两条记录,它们在X属性(或属性组)上的值相同,而在Y属性上的值不同。这也就是“函数依赖”名字的由来,类似于函数关系 y = f(x),在x的值确定的情况下,y的值一定是确定的。

例如,对于表3中的数据,找不到任何一条记录,它们的学号相同而对应的姓名不同。所以我们可以说姓名函数依赖于学号,写作 学号 → 姓名。但是反过来,因为可能出现同名的学生,所以有可能不同的两条学生记录,它们在姓名上的值相同,但对应的学号不同,所以我们不能说学号函数依赖于姓名。表中其他的函数依赖关系还有如:

  • 系名 → 系主任
  • 学号 → 系主任
  • (学号,课名) → 分数

但以下函数依赖关系则不成立:

  • 学号 → 课名
  • 学号 → 分数
  • 课名 → 系主任
  • (学号,课名) → 姓名

从“函数依赖”这个概念展开,还会有三个概念:
完全函数依赖
在一张表中,若 X → Y,且对于 X 的任何一个真子集(假如属性组 X 包含超过一个属性的话),X ’ → Y 不成立,那么我们称 Y 对于 X 完全函数依赖,记作 X F→ Y。(那个F应该写在箭头的正上方,没办法打出来……,正确的写法如图1)

图1
例如:
-学号 F→ 姓名
-(学号,课名) F→ 分数 (注:因为同一个的学号对应的分数不确定,同一个课名对应的分数也不确定)

部分函数依赖
假如 Y 函数依赖于 X,但同时 Y 并不完全函数依赖于 X,那么我们就称 Y 部分函数依赖于 X,记作 X P→ Y,如图2。

图2
例如:
-(学号,课名) P→ 姓名

传递函数依赖
假如 Z 函数依赖于 Y,且 Y 函数依赖于 X (『Y 不包含于 X,且 X 不函数依赖于 Y』这个前提),那么我们就称 Z 传递函数依赖于 X ,记作 X T→ Z,如图3。

图3


设 K 为某表中的一个属性或属性组,若除 K 之外的所有属性都完全函数依赖于 K(这个“完全”不要漏了),那么我们称 K 为候选码,简称为码。在实际中我们通常可以理解为:假如当 K 确定的情况下,该表除 K 之外的所有属性的值也就随之确定,那么 K 就是码。一张表中可以有超过一个码。(实际应用中为了方便,通常选择其中的一个码作为主码)

例如:

对于表3,(学号、课名)这个属性组就是码。该表中有且仅有这一个码。(假设所有课没有重名的情况)

非主属性
包含在任何一个码中的属性成为主属性

例如:
对于表3,主属性就有两个,学号 与 课名。

终于可以回过来看2NF了。首先,我们需要判断,表3是否符合2NF的要求?根据2NF的定义,判断的依据实际上就是看数据表中是否存在非主属性对于码的部分函数依赖。若存在,则数据表最高只符合1NF的要求,若不存在,则符合2NF的要求。判断的方法是:
- 第一步:找出数据表中所有的码。
- 第二步:根据第一步所得到的码,找出所有的主属性。
- 第三步:数据表中,除去所有的主属性,剩下的就都是非主属性了。
- 第四步:查看是否存在非主属性对码的部分函数依赖。

对于表3,根据前面所说的四步,我们可以这么做:
第一步:
- 查看所有每一单个属性,当它的值确定了,是否剩下的所有属性值都能确定。
- 查看所有包含有两个属性的属性组,当它的值确定了,是否剩下的所有属性值都能确定。
- ……
- 查看所有包含了六个属性,也就是所有属性的属性组,当它的值确定了,是否剩下的所有属性值都能确定。

看起来很麻烦是吧,但是这里有一个诀窍,就是假如A是码,那么所有包含了A的属性组,如(A,B)、(A,C)、(A,B,C)等等,都不是码了(因为作为码的要求里有一个“完全函数依赖”)。

图4表示了表中所有的函数依赖关系:

图4
这一步完成以后,可以得到,表3的码只有一个,就是(学号、课名)。

第二步:
主属性有两个:学号 与 课名

第三步:
非主属性有四个:姓名、系名、系主任、分数

第四步:
对于(学号,课名) → 姓名,有 学号 → 姓名,存在非主属性 姓名 对码(学号,课名)的部分函数依赖。
对于(学号,课名) → 系名,有 学号 → 系名,存在非主属性 系名 对码(学号,课名)的部分函数依赖。
对于(学号,课名) → 系主任,有 学号 → 系主任,存在非主属性 对码(学号,课名)的部分函数依赖。所以表3存在非主属性对于码的部分函数依赖,最高只符合1NF的要求,不符合2NF的要求。

为了让表3符合2NF的要求,我们必须消除这些部分函数依赖,只有一个办法,就是将大数据表拆分成两个或者更多个更小的数据表,在拆分的过程中,要达到更高一级范式的要求,这个过程叫做”模式分解“。模式分解的方法不是唯一的,以下是其中一种方法:
选课(学号,课名,分数)
学生(学号,姓名,系名,系主任)

我们先来判断以下,选课表与学生表,是否符合了2NF的要求?
对于选课表,其码是(学号,课名),主属性是学号和课名,非主属性是分数,学号确定,并不能唯一确定分数,课名确定,也不能唯一确定分数,所以不存在非主属性分数对于码 (学号,课名)的部分函数依赖,所以此表符合2NF的要求。

对于学生表,其码是学号,主属性是学号,非主属性是姓名、系名和系主任,因为码只有一个属性,所以不可能存在非主属性对于码 的部分函数依赖,所以此表符合2NF的要求。

图5表示了模式分解以后的新的函数依赖关系

图5
表4表示了模式分解以后新的数据

表4
(这里还涉及到一个如何进行模式分解才是正确的知识点,先不介绍了)

现在我们来看一下,进行同样的操作,是否还存在着之前的那些问题?

  1. 李小明转系到法律系只需要修改一次李小明对应的系的值即可。——有改进
  2. 数据冗余是否减少了?学生的姓名、系名与系主任,不再像之前一样重复那么多次了。——有改进
  3. 删除某个系中所有的学生记录该系的信息仍然全部丢失。——无改进
  4. 插入一个尚无学生的新系的信息。因为学生表的码是学号,不能为空,所以此操作不被允许。——无改进

所以说,仅仅符合2NF的要求,很多情况下还是不够的,而出现问题的原因,在于仍然存在非主属性系主任对于码学号的传递函数依赖。为了能进一步解决这些问题,我们还需要将符合2NF要求的数据表改进为符合3NF的要求。


第三范式

3NF在2NF的基础之上,消除了非主属性对于码的传递函数依赖。也就是说, 如果存在非主属性对于码的传递函数依赖,则不符合3NF的要求。

接下来我们看看表4中的设计,是否符合3NF的要求。

对于选课表,主码为(学号,课名),主属性为学号和课名,非主属性只有一个,为分数,不可能存在传递函数依赖,所以选课表的设计,符合3NF的要求。

对于学生表,主码为学号,主属性为学号,非主属性为姓名、系名和系主任。因为 学号 → 系名,同时 系名 → 系主任,所以存在非主属性系主任对于码学号的传递函数依赖,所以学生表的设计,不符合3NF的要求。

为了让数据表设计达到3NF,我们必须进一步进行模式分解为以下形式:
选课(学号,课名,分数)
学生(学号,姓名,系名)
系(系名,系主任)

对于选课表,符合3NF的要求,之前已经分析过了。

对于学生表,码为学号,主属性为学号,非主属性为系名,不可能存在非主属性对于码的传递函数依赖,所以符合3NF的要求。

对于系表,码为系名,主属性为系名,非主属性为系主任,不可能存在非主属性对于码的传递函数依赖(至少要有三个属性才可能存在传递函数依赖关系),所以符合3NF的要求。

新的函数依赖关系如图6


图6

新的数据表如表5

表5
现在我们来看一下,进行同样的操作,是否还存在着之前的那些问题?

  1. 删除某个系中所有的学生记录该系的信息不会丢失。——有改进
  2. 插入一个尚无学生的新系的信息。因为系表与学生表目前是独立的两张表,所以不影响。——有改进
  3. 数据冗余更加少了。——有改进

结论

由此可见,符合3NF要求的数据库设计,基本上解决了数据冗余过大,插入异常,修改异常,删除异常的问题。当然,在实际中,往往为了性能上或者应对扩展的需要,经常 做到2NF或者1NF,但是作为数据库设计人员,至少应该知道,3NF的要求是怎样的。


参考文章:
https://www.zhihu.com/question/24696366

数据库1NF 2NF 3NF范式解释相关推荐

  1. 理解数据库 1NF 2NF 3NF BCNF

    参考文章写的非常不错,给自己解惑了 参考文章: https://www.zhihu.com/question/24696366 首先是范式的定义 范式是"符合某一种级别的关系模式的集合,表示 ...

  2. 数据库三大范式(1NF,2NF,3NF)及ER图

    数据库三大范式(1NF,2NF,3NF)及ER图 百度官方解释: 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据 ...

  3. 3nf mysql表_数据库三大范式(1NF,2NF,3NF)及ER图

    数据库三大范式(1NF,2NF,3NF)及ER图 百度官方解释: 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据 ...

  4. 数据库范式解析(1NF 2NF 3NF BCNF)

    数据库设计范式是关系型数据库的设计准则.其目的在于通过规划设计使得数据库结构合理,尽量减少数据冗余,消除存储异常,方便数据的插入.更新和删除操作.目前常用范式包括1NF(第一范式).2NF(第二范式) ...

  5. 【数据库】范式理解:1NF,2NF,3NF,BCNF,4NF详析

    数据库入门(一)范式理解:1NF,2NF,3NF,BCNF,4NF详析 引言 范式种类 第一范式(1NF) 符合1NF的关系中的每个属性都不可再分 存在问题 第二范式(2NF) 在1NF基础上消除了非 ...

  6. 数据库范式1NF 2NF 3NF详细阐述

    范式:关系数据库中的关系是要满足一定要求的,满足不同程度要求的不同范式.满足最低要求的叫第一范式,简称1NF ,在第一范式中满足进一步要求的为第二范式,其余以此类推.通俗来说是满足数据库关系表中的一套 ...

  7. 数据库随笔-1NF,2NF,3NF详解

    数据库随笔-1NF,2NF,3NF详解 基础概念 通过表的更新来举例说明 总结 基础概念 1. 第一范式(1NF):每一列都是不可分割的原子数据项 2. 第二范式(2NF):在1NF的基础上,非码属性 ...

  8. 1NF | 2NF | 3NF的区分以及什么是函数依赖、部分函数依赖、值传递依赖(最详细的讲解1NF、2NF、3NF的关系)

    1NF | 2NF | 3NF的区分以及什么是函数依赖.部分函数依赖.值传递依赖 符合3NF一定符合2NF.一定符合1IF 简单区分.2NF不存在部分函数依赖,3NF不存在传递函数依赖 第一范式1NF ...

  9. 数据库六种范式详解(1NF/2NF/3NF/BCNF/4NF/5NF)

    目录 数据库的基本概念 函数依赖 函数依赖的定义 函数依赖与属性的关系 六种范式 第一范式(1NF) 第二范式(2NF) 第三范式(3NF) 巴斯-科德范式(BCNF,Boyce-Codd Norma ...

最新文章

  1. 腾讯再次海选AI项目,1500进40,医疗零售机器人成新风向
  2. linux shell之删除当前文件夹不包含文件1和文件2的其他所有文件
  3. 历史上知名的反转现场
  4. H5 水球加载动画 - canvas应用篇
  5. mysql表连接_SELECT中的多表连接
  6. 当我们安装使用时,会出现eclipse启动不了,出现“Java was started but returned exit code=13......”的问题...
  7. Tomcat配置阿里云免费的SLL证书
  8. springday04-go1
  9. 32 管道 共享数据 进程池
  10. 甲骨文每季安全更新再修补297个漏洞
  11. atitit. 日志系统的原则and设计and最佳实践(1)-----原理理论总结.
  12. masm5安装教程_masm5 1、下载个masm5.0(简单 联合开发网 - pudn.com
  13. Vue后台管理系统项目总结
  14. html导出excel加边框,利用js对象Blob导出的excel,有办法把表格的边框给浮现出来...
  15. 山东理工大学ACM平台题答案 1235 计算球体积
  16. IDEA translation翻译插件报错-》更新TKK失败请检查网络
  17. cuda the launch timed out and was terminated windows11解决方案 关闭TDR
  18. win10家庭版的常见问题1
  19. 深入理解Flash的沙箱
  20. VC 获取任务栏窗口的句柄

热门文章

  1. 后台管理使用微信扫码登录(小程序登录)
  2. 微星迫击炮B550M MORTAR WIFI 插三根内存不开机、黑屏、蓝屏、BIOS报错
  3. 【spinning up】2.2 功能超全的强化学习画图脚本
  4. 数据分析(学习笔记)
  5. Sepic电路的参数计算及仿真
  6. websocket 给服务端发送太长数据处理(The decoded text message was too big for the output buffer and the endpoint )
  7. peewee操作mysql_Peewee 使用
  8. python海龟教程_Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 7. 条件循环...
  9. python peewee 批量插入
  10. java i18n utf_Java国际化(i18n)字符串与Unicode转换