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

    数据库有三大范式和BC范式,我们来详细探讨一下:
    首先三大范式:

    第一范式

    第一范式(1NF):表中所有属性都不能再分,都应该是原子值。
    这也是数据表的最低的最基本的要求。

    第二范式

    第二范式(2NF):在满足第一范式的前提下,还要求每一个非主属性都要完全依赖于任何一个候选码

    上面这句话听起来比较抽象,其实也好理解。(下面的主键(限第二范式中)其实指:主键或候选码,这么写的看起来太绕就简写成主键了,大家注意一下)

    它的意思就是指,每一个非主属性都应该和主键有关(不能只和主键的一部分相关,这是指联合主键),即一个表只做一件事。

    举个例子,下面是一个关系,

    Student(Sno, Sdept, Sloc, Cno, Grade)
    
    • Sno:学号
    • Sdept:学生所在的系
    • Sloc:学生的住处,每个系的学生住在一起
    • Cno:课程编号
    • Grade:该学生该课程的成绩
      其中该关系的主键为(Sno, Cno)

    显然该关系就不符合第二范式,而这样会出现很多的问题。
    (1)插入异常
    如果要插入一个学生,但是该学生还未选课,那么他就没有Cno,而主键又不能为空,那么他就插不进去…
    (2)删除异常
    假设一个学生本来只选了一门课,现在他一门课都不想选了,想把这门课退掉,那么这个学生的所有信息也会随之而被删掉…
    (3)修改复杂
    如果一个学生转系了,那么修改起来就很麻烦,冗余数据很多。本来只要改Sdept就行了,但是现在还需要对它的Sloc进行修改,而且如果他选了5门课,则需要修改SdeptSloc五次。

    所以应该将其分成两个表:

    CJ(Sno,Cno,Grade)	/*成绩表*/
    StudentInfo(Sno,Sdept,Sloc)	/*学生基础信息表*/
    

    第三范式

    第三范式(3NF):在满足第二范式的前提下,还要求表中不存在传递依赖,即表中每一列都要与主键直接相关,而非间接相关。

    举个栗子:

    订单表(订单号, 订购日期, 顾客编号, 顾客名)
    

    上面表中,显然订单号是主键,而顾客名与订单号却是间接相关的,他们中间通过顾客编号相连。
    这显然是不满足第三范式的,因此需要将其进行修改:

    订单表(订单号,订购日期,顾客编号)
    顾客表(顾客编号,顾客名)
    

    这样显然也是一种避免冗余的手段。

    如何区分这三种范式呢?

    第一范式:表中的每一列都是最小的单元,任何一列都不能再进行拆分了;
    第二范式:表中所有的列都应该是和主键(的全体)完全相关的,即不能只和主键的某一部分相关;
    第三范式:表中每一个非主属性都要和主键直接相关,即不要在表中出现太多另外一个实体的信息,只需要出现它的id就行了。

    范式之所以叫做范式,就是因为它给数据库的设计提供了一种规范,能够最大可能的避免犯错,也减少了数据的冗余,提高数据库效率。

    附加:BC范式(BCNF)

    数据库的三大范式只是最基本的,而BC范式也常与他们放到一起讨论,因为BCNF也被称为修正的第三范式,又或者说是扩充的第三范式。

    为什么叫修正的第三范式?那么表示第三范式肯定有所缺漏,那么缺漏是什么呢?又如何补救呢?

    我们看到第三范式的要求是每一个非主属性都要直接依赖于主属性,看似完美,可是如果除了主属性外,还有一个候选码呢?
    显然从定义可以知道,这个主属性肯定能和候选码一一对应的,那这样岂不是又会造成冗余?
    觉得很抽象吗?举个例子:

    仓库(仓库编号,货物编号,仓库管理员编号)
    

    其中每一个仓库管理员只管理一个仓库。
    那么我们可以发现这里其实主码可以有两种,分别是:

    • (仓库编号) 可唯一确定 (仓库管理员编号,货物编号)
    • (仓库管理员编号) 可唯一确定 (仓库编号,货物编号)

    必须要承认上述关系是符合第三范式的吧,但是有没有觉得这样仓库管理员编号会出现大量的没必要的冗余啊,因此BC范式就是解决这个问题的,需要将其改为两个表,顺便可以将货物的数量加进来。

    至于为什么上面关系中我不将货物数量加进来,是因为一旦加进来后那个关系就不符合第二范式了,想想看,如果加入货物数量,那么主键就变成了(仓库编号,货物编号),可是仓库管理员只与仓库编号有关,不依赖于货物编号了呀,就不构成对主键的完全依赖关系了。

    下面放上BC范式的修改版:

    仓库与管理员表(仓库编号,仓库管理员编号)
    仓库货物表(仓库编号,货物编号,货物数量)
    

    参考资料:
    https://www.cnblogs.com/waj6511988/p/7027127.html
    https://blog.csdn.net/javanotes/article/details/81368715
    https://www.cnblogs.com/knowledgesea/p/3667395.html
    https://blog.csdn.net/u014458048/article/details/56678698

  • 相关阅读:
    Centos7使用systemd 管理elasticsearch,创建elasticsearch服务
    nginx日志切割的2种方法
    sudo linux
    redis 重启不了
    类与对象
    用Python写一个小的购物车
    包的使用
    Python模块简介
    zookeeper & Dubbo
    迭代器 & 生成器
  • 原文地址:https://www.cnblogs.com/yinyoupoet/p/13287430.html
Copyright © 2011-2022 走看看