zoukankan      html  css  js  c++  java
  • 数据库的范式

    2019-07-16

    关键字:1NF, 2NF, 3NF, BCNF, 4NF, 5NF、三范式


    前言

    数据库在设计过程中很重要的一个步骤就是根据我们所了解到的业务信息来进行“数据库建模”。

    数据库模型的好坏直接关系到我们后面的开发工作的难易程度,更重要的是会影响到系统上线后的运维工作的可操作性。

    数据库在建模过程中对库表范式的选型也很重要,我们必须在建模时期就敲定好,因为后续如果要改变范式那可是很困难的。

    数据库的范式说白了就是我们要如何来根据业务设计数据表

    数据库范式的目的是为了减少数据冗余,解除数据之间的业务耦合,提升灵活性

    数据库范式目前共有六种

    1、第一范式(1NF)

    2、第二范式(2NF)

    3、第三范式(3NF)

    4、巴斯•科德范式(BCNF)

    5、第四范式(4NF)

    6、第五范式(5NF)

    数据库范式越高,对于设计范式的目的的满足程度就越好,但同样的维护起来也就越困难,毕竟凡事都具有双面性~

    一般而言,设定到第三范式就可以了,它各方面的表现最为中庸均衡。越往上就越少见,甚至有些范式只存在于传说中。比如 第六范式。

    下面我们就针对这几个范式逐个来了解一下它们的要求,并给出一个小例子以加深理解。

    第一范式(1NF)

    第一范式的核心就是“原子性”!它通常要满足如下几点要求

    1、二维数据表

    2、每一列的数据都是相同含义的

    3、每个元素不可出现多值的情况

    4、不得出现相同含义的字段

    5、确定主键

    首先我们得来了解了解什么才是“原子性”。

    原子性就是所描述的事物的单位已经达到最小程度,已经不可再细分了。多说无益,直接来看看下面的数据表。

    像上面这张表,班级部分就不是原子性的。因为它还可以再进一步拆分成年级和班级。上面这张数据表的符合原子性的形式应该如下图表所示

    其次是了解第一范式下的其它几点要求。先看第 1 点,数据库中的数据源可能有多种多样,但对于数据库建模而言,不管你什么来源的数据,不管你是结构化的还是半结构化的亦或是非结构化的,都得转成统一格式的二维数据表。而且这里所说的数据库范式都是基于关系型数据库而言的。

    第 2 点,同一列中的所有数据所表示的含义必须是同一种类型的。举个小例子,下面所示的数据表就不满足于这一条

    上图所示数据表的成绩列就是设计不合理的示例。一个合格的数据表是绝对不能出现这种情况的。而对于这种情况的解决办法也简单,将不同类型的值拆成多个列就是了。如下图所示

    至于第 3 点与第 4 点,应该将它们一起看待。直接看图

    对于这种某一项的值有多个的情况,一种可能的做法就是将多个值以逗号分隔符隔开。但很多人都能意识到这样做很不妥。于是又可能会有以下升级版本

    但这样做也还是不妥。同一种字段在一张表中出现了两次,重复定义了。符合范式的做法应当是将这张表拆分成两张表,如下图所示

    第 5 点就很简单了。对于我们的关系型数据库表,都得确定好主键,或复合主键或单主键。

    第二范式(2NF)

    在了解了第一范式以后,剩下的范式就稍微没这么多“内容”了。前面说过,每一级范式都是基于它的上一级范式添加了一层限制的。

    第二范式就是在第一范式的基础之上添加了一个“关系依赖”的限制。

    其实第二范式主要用于限制拥有复合主键的数据表。第二范式要求所有非主键字段必须要依赖于所有的主键,而不能出现某些普通字段仅依赖于部分主键的情况

    我们直接来看一个例子,假设有如下图所示数据表

    在这张表中拥有复合主键:学号、课程号。

    我们可以发现,成绩是既依赖于课程号主键又依赖于学生学号主键的,但授课老师仅仅依赖于课程号主键,而与学号没有关系。

    因此,这张表不满足于第二范式。符合于第二范式的表形式应该如下图表所示

    第三范式(3NF)

    第三范式自然是在第二范式的基础之上又加了一种限制关系。

    第三范式要求任何非主键字段不得依赖于其它非主键字段,非主键字段只能依赖于主键字段

    第三范式的目的是要消除“传递依赖”关系的。通俗地解释一下传递依赖,假设有一个主键A,以及普通键B和普通键C。现有普通键B依赖于主键A,而普通键C不依赖于主键A。但是,普通键C会依赖于普通键B。那这就会导致普通键C间接依赖于主键A。这种间接依赖关系就是所谓的“传递依赖”关系。

    我们还是来看一下具体的例子,还是拿上面学生信息数据库的例子来看。假设有一张表,其结构如下图所示

    在上面的例子中系编号是主键。我们可以明显看出,学号是会依赖于主键系编号的,但姓名不会依赖于系编号只会依赖于学号。由此一来姓名就会间接地依赖于系编号,这是不符合第三范式要求的。要修改的符合第三范式要求,只需要将它们拆分成两张表即可,如下图所示

    巴斯•科德范式(BCNF)

    BCNF在第三范式的基础之上进一步限定了属性之间的关系。它要求任何字段都不能依赖于非主健字段。因为这里已经满足了第三范式了,所以这个范式的要求其实可以简化为:主键字段不得依赖于非主键字段。

    当满足第三范式的数据表有以下两种基本条件时就有可能会不满足巴斯科德范式

    1、有联合主键

    2、有重复的候选健

    第四范式(4NF)

    从BCNF开始的范式,就专门研究主键字段,而且还得是联合主键的情况。

    第四范式的目的是要消除多值依赖。什么是多值依赖呢?

    假设有三个字段作联合主键,它们分别为 A, B, C。AB, AC都存在关系,B和C没关系。

    这样一来就会导致B和C存在间接依赖关系。第四范式要做的就是消除这种间接依赖的关系。解决的办法自然也是拆拆拆。

    第五范式(5NF)

    第五范式研究的仍然是具有联合主键的表。

    假设某张表有三个联合主键,分别为 A, B, C。若AB有关系,AC有关系,BC也有关系。那么这样的表就是满足第四范式的,但是它却不满足第五范式。因为这种主键两两之间都有关系的表它存在“连接依赖”。

    解决的办法仍然是拆分成多个表。每两个主键拆成成一张表。

    ----

    再次强调,在日常工作中,数据库表的范式设计成满足到第三范式就可以了,偶尔可能会出现意外满足了BCNF的情况。再往上的范式就不建议了,因为范式越高虽然数据库越灵活,但是反过来它使用起来也越困难。凡事都有它的两面性。第三范式就是一个折中的选择。


  • 相关阅读:
    Algorithm Gossip (48) 上三角、下三角、对称矩阵
    .Algorithm Gossip (47) 多维矩阵转一维矩阵
    Algorithm Gossip (46) 稀疏矩阵存储
    Algorithm Gossip (45) 费氏搜寻法
    Algorithm Gossip (44) 插补搜寻法
    Algorithm Gossip (43) 二分搜寻法
    Algorithm Gossip (42) 循序搜寻法(使用卫兵)
    Algorithm Gossip (41) 基数排序法
    Algorithm Gossip (40) 合并排序法
    AlgorithmGossip (39) 快速排序法 ( 三 )
  • 原文地址:https://www.cnblogs.com/chorm590/p/11106259.html
Copyright © 2011-2022 走看看