数据库范式

开篇

有时候理论这东西真的是一直处于学了忘,忘了学,学了忘这种死循环中。一直没有什么办法去跳脱出来。这不,今天又啃起数据库范式来了。


概要

范式:是符合某一级别的关系模式的集合。

数据库范式:再设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数控冗余越小。

所谓的范式,个人理解的范式就像银行的客户评级体系一般。

如:一个客户办了银行卡,并且一年内的流水小于50k的,那么该客户可以申请为普通客户。如果一个客户一年内流水小于150k的,那该客户可以申请为VIP客户。同理balabala

如此,这个流水额度评断客户级别即范式。高级别的范式是符合低级别范式的,反之则不行。就像VIP客户可以申请为普通客户,但是普通客户不能申请为VIP客户。


范式简介

目前数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)、第五范式(5NF,又称为完美范式)。一般来说,数据库只需要满足第三范式就好了,再高也就是BCNF了。


范式介绍

第一范式

数据库表中的所有字段值都是不可拆分的原子数据项。

现在绝大部分关系型数据库在建表的时候就已经保证了 1NF 。

如下图就是不符合 1NF 的要求:

image

如下就是符合 1NF 要求的设计:

image

如果只是满足 1NF 要求,那么数据库中必定还会存在许多冗余数据。

如上表中的冗余数据过多,班主任信息在同个班级的学生下都存储了一份,这是不必要的。所以我们可以根据第二范式来减少冗余。

第二范式

在 1NF 的基础上,非码属性必须完全依赖于候选码。(关于候选码,主属性介绍)

要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性

用人话来说就是必须有主键(或者联合主键),而且可以根据这个主键区分出每一条记录。如果是联合主键的话,那么不能只根据联合中的其中一个字段区分出每一条记录,一定要是组合后的主键才能区分。

举个例子:在一个学校里面,老师要通过广播找到学生“张伟”,但是呢,好巧不巧的这个学校正好有3个张伟,所以老师就不能直接用名字来作为通知对应的学生,而是可以说“学号为xxxxx的同学到教务处来一下”或者说“xxx年级xxx班的张伟同学到教务处来一下”。

这里的学号就是主键,而xxx年级+xxx班+张伟 就是联合主键。

在 MySQL InnoDB 存储引擎中,是必须要有主键的,即使用户没有设置主键,MySQL 也会建立一个隐藏的主键。

第三范式(来自百度百科,个人以为这段解释非常易懂)

在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

简而言之,第三范式(3NF)要求一个关系中不包含已在其它关系已包含的非主关键字信息。

例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性,也就是在满足2NF的基础上,任何非主属性不得传递依赖于主属性。

BCNF

在3NF基础上,任何非主属性不能对主键子集依赖(在3NF基础上消除对主码子集的依赖)

  • 所有非主属性对每一个码都是完全函数依赖。
  • 所有主属性对每一个不包含它的码也是完全函数依赖。
  • 没有任何属性完全函数依赖于非码的任何一组属性。

看如下例子 :

学生 老师 课程
王小明 科斯 数据结构

假设每个老师只教授一门课程。

则候选码有:

(学生,老师) -> 课程

(学生,课程) -> 老师

这两个码由两个属性组成,而且它们是相互交叉的关系,所以不存在传递依赖,所以符合 3NF 。

但是由于 教师 -> 课程,(主键的一部分被另一部分决定,即不符合 BCNF 中的第二条约束),所以不符合 BCNF 。

可以改成如下两张表即符合 BCNF :

学生教师关系表:

学生 老师
王小明 科斯

教师信息表:

老师 课程
科斯 数据结构

关于候选键/码,主键,主属性的介绍:

image

image

image


参考:

百度百科-数据库范式

如何解释关系数据库的第一第二第三范式? - 刘慰的回答 - 知乎

范式相关知识强化

Comments
Write a Comment