乐趣区

关于mysql:三大范式再认识

前言

说起三大范式,我脑海里第一反馈就是这几句话:

  • 当实体 A 与实体 B 之间的关系是一对一时,会把实体 A 的主键作为 实体 B 的外键。当然关系是一对一时,反过来也能够,即把 实体 B 的主键当做实体 A 的外键;
  • 当实体 A 与实体 B 之间的关系是一对多时,会把 A 的主键当做实体 B 的外键;
  • 当实体 A 与实体 B 之间的关系是多对多时,通常会思考建一张新表来保留这两个实体之间的关系。

然而有时候实体与实体之间的关系并不是非常容易的看进去,所以靠这些了解并不足以设计出符合规范的表构造。在读了相应的材料后,发现自己对三大范式的了解是十分肤浅的、浮浅的,所以就写了这篇博客来记录本人对三大范式重新认识的过程。

什么是范式(NF)?

在了解三大范式之前,须要明确什么是范式(NF)?

依照教材中的定义,范式是:

合乎某一种级别的关系模式的汇合,示意一个关系外部各属性之间的分割的合理化水平。

能够了解为:一张数据表的表构造所合乎的某种设计标准的级别

三大范式定义

以下是三大范式的定义:

  • 第一范式:合乎 1NF 的关系中的每个属性都不可再分。
  • 第二范式:2NF1NF 的根底之上,打消了非主属性对于码的局部函数依赖。
  • 第三范式:3NF2NF 的根底之上,打消了非主属性对于码的传递函数依赖。

说实话,我一开始看到第二范式和第三范式的定义时,感到十分蛊惑:

  • 什么是非主属性?
  • 什么是码?
  • 范式的定义为什么和函数无关?

然而在了解了这些概念之后,才意识到意识到这几条定义是如此的准确。

在了解“非主属性”和“码”之前,须要先彻底搞明确什么是“函数依赖”,因为“非主属性”和“码”的概念是建设在“函数依赖”的概念之上的。

什么是函数依赖?

若在一张表中,在属性(或属性组)X 的值确定的状况下,必然能确定属性 Y 的值,那么就能够说 Y 函数依赖于 X,写作 X → Y。

光看概念可能不太好了解什么是函数依赖,还是须要通过一个例子来了解。

学生表如下:

学号 姓名 性别 年龄
1420233906 罗辑 21
1420233907 云天明 22
1420233908 章北海 23
1420233909 程心 20

这张学生表有四个属性:学号、姓名、性别、年龄。咱们晓得一个学号对应一个学生,如果你的班主任问你 1420233906 是谁,你就能够通知他 1420233906 是罗辑,除此之外,你还能通知你的班主任,罗辑是男的,21 岁。

换句话说:

  • 在学号确定的状况下,就必然能确定姓名的值,即姓名 函数依赖于 学号,写作姓名 → 学号;
  • 在学号确定的状况下,就必然能确定性别的值,即性别 函数依赖于 学号,写作性别 → 学号;
  • 在学号确定的状况下,就必然能确定年龄的值,即年龄 函数依赖于 学号,写作年龄 → 学号;

还能在学生表中找到其余的函数依赖关系吗?答案是否定的。

如果学生表中,只有这四条记录,如同是能够通过姓名来确定学号、性别、年龄的值。然而在大多数班中必定存在 同名同姓 的学生,例如张伟:

学号 姓名 性别 年龄
1420233906 罗辑 21
1420233907 云天明 22
1420233908 章北海 23
1420233909 程心 20
1420233909 张伟 21
1420233910 张伟 22

尽管同叫张伟,但却是两个不同的学生。当数学老师叫张伟时,两个张伟可能同时站起来。即在姓名确定的状况下,无奈确定学号的值,无奈确定性别的值也无奈确定年龄的值。同理:

  • 在性别确认的状况下,无奈确定其余任意一个属性的值;
  • 在年龄确认的状况下,无奈确定其余任意一个属性的值;

再来看一个更难的例子:

学号 姓名 系名 系主任 课名 分数
1420233906 罗辑 机电工程系 艾 AA 高等数学 99
1420233907 罗辑 机电工程系 艾 AA 大学英语 98
1420233908 罗辑 机电工程系 艾 AA 大学物理 97
1420233909 程心 经济系 维德 高等数学 88
1420233909 程心 经济系 维德 毛概 88
1420233910 程心 经济系 维德 大学英语 88

在这张表中存在哪些函数依赖关系呢?

  • 学号 → 姓名
  • 学号 → 系名(一个学生只属于一个系)
  • 系名 → 系主任(一个系只有一个系主任)
  • 学号 → 系主任(一个学生只属于一个系、一个系只有一个系主任,即在学号确定的状况下,必然能够确认该学生所属系的系主任)
  • (学号,课名)→ 分数

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

  • 学号 → 课名
  • 学号 → 分数
  • 课名 → 分数

从“函数依赖”这个概念开展,还会有三个概念:

1)齐全函数依赖

在一张表中,若 X → Y,且对于 X 的任何一个真子集(如果属性组 X 蕴含超过一个属性的话),X ‘ → Y 不成立,那么咱们称 Y 对于 X 齐全函数依赖,记作 X F→ Y

例如:(学号,课名)F→ 分数,即分数齐全函数依赖于(学号,课名)属性组。

  • 属性 Y 要齐全函数依赖于属性(组)X 的前提是:属性 Y 要函数依赖于属性(组)X,分数函数依赖于(学号,课名),第一条满足;
  • (学号,课名)是一个属性组,超过一个属性,它的真子集有{学号}、{课名},无奈只通过学号来确定分数,也无奈只通过课名来确定分数,故满足对于(学号、课名)的任何一个真子集,X’ → Y 不成立。

所以分数齐全函数依赖于(学号,课名)属性组成立。

2)局部函数依赖

如果 Y 函数依赖于 X,但同时 Y 并不齐全函数依赖于 X,那么咱们就称 Y 局部函数依赖于 X,记作 X P→ Y

例如:(学号,课名)P→ 姓名,即姓名局部函数依赖于(学号,课名)组。

  • 首先姓名函数依赖于(学号,课名)属性组成立;
  • (学号,课名)的真子集为{学号}、{课名},在这些真子集中,能够通过学号来确定姓名,即姓名函数依赖于学号,故姓名不齐全函数依赖于(学号,课名)属性组,即姓名局部函数依赖于(学号,课名)。

3)传递函数依赖

如果 Y 不蕴含于 X,且 X 不函数依赖于 Y,Z 函数依赖于 Y,且 Y 函数依赖于 X,那么咱们就称 Z 传递函数依赖于 X,记作 X T→ Z。

什么是码?

设 K 为某表中的一个属性或属性组,若除 K 之外的所有属性都齐全函数依赖于 K(这个“齐全”不要漏了),那么咱们称 K 为候选码,简称为码。

什么是非主属性

主属性之外的属性就是非主属性。

参考

  1. 第一范式、第二范式、第三范式详解 |☆☆☆☆☆
  2. 三张图搞透第一范式 (1NF)、第二范式(2NF) 和第三范式 (3NF) 的区别 |☆☆☆☆
  3. 真子集和子集有什么区别?|☆☆
  4. 数据库的三大范式(原理 + 例子详解)|☆☆☆
退出移动版