范式(Normal Format),是一种离散数学中的知识,是为了解决一种数据的存储与优化的问题,保存数据的存储之后,凡是能够通过关系寻找出来的数据,坚决不再重复存储终极目标是为了减少数据的冗余。范式是一种分层结构的规范,分为六层:每一次层都比上一层更加严格,若要满足下一层范式,前提是满足上一层范式。

六层范式:1NF, 2NF, 3NF, 4NF, 5NF, 6NF, 1NF是最底层,要求最低,6NF是最高层,最严格。

Mysql属于关系型数据库,有空间浪费,也是需要考虑节省存储空间,这个与范式所有解决的问题不谋而合。在设计数据库的时候,会利用范式来指导设计。但是数据库不单是要解决空间问题,还要保证效率问题。范式只为解决空间问题,所以数据库的设计又不可能完全按照范式的要求去设计和实现,一般情况下,只有前三种范式需要满足。范式只是指导意义,没有强制规范要求。

第一范式

定义:在设计表存储数据的时候,如果表中设计的字段存储的数据,在取出来使用之前还需要额外的处理(拆分),那么说表的设计不满足第一范式,第一范式要求字段的数据具有原子性,也就是不可拆分。

举例下面讲师表

讲师

性别

班级

课程

时间

代课时间(开始和结束)

张三

204

Java基础

30天

2018-01-01,2018-01-31

 

 

 

 

 

 

看上面这个表格,其实是可以存储数据,但是不符合第一范式。理由是这样的,如果要查询一个老师是从什么时间开始代课和什么时间结束代课。这样查询结果应该是两个字段,但是当前表只能给出一个字段,也就是查询之后还需要拆分数据。

解决方案,把代课时间分拆两个字段,一个开始一个结束。

讲师

性别

班级

课程

时间

开始

结束

张三

204

Java基础

30天

2018-01-01

2018-01-31

 

 

 

 

 

 

 

第二范式

定义:在数据表设计的过程中,如果有复合主键(多字段主键),且表中有字段并不是由整个主键来确定,而是依赖主键中的某个字段(主键部分),存在字段依赖主键部分的问题称之为部分依赖,第二范式就是解决表数据中不允许出现部分依赖。

举例:讲师代课表

讲师(P)

性别

教室

班级(P)

时间

开始

结束

张三

204

Java基础

30天

2018-01-01

2018-01-31

 

 

 

 

 

 

 

以上表中有两个P。表示讲师和班级两个字段组成复合主键约束。一个老师在一个班永远只带一个阶段的课。代课时间,开始和结束时间都与当前的代课主键有关系,但是性别并不依赖班级,教室不依赖讲师,性别只依赖讲师,教室只依赖班级。这个就形成了部分依赖,符合第二范式。

解决方案1:可以将性别和讲师单独成表,班级和教室单独成表。

解决方案2:取消复合主键,使用逻辑主键。

我们来介绍方案2

ID(P)

讲师

性别

教室

班级

时间

开始

结束

1

张三

204

Java基础

30天

2018-01-01

2018-01-31

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

当前增加了ID这个逻辑主键,取消讲师和班级复合主键。

第三范式

要满足第三范式,必须满足第二范式。理论上讲,应该一张表中的所有字段都应该直接依赖主键(逻辑主键,代表的是业务主键),如果表设计中存在一个字段并不直接依赖主键,而是通过某个非主键字段依赖,最终实现依赖主键,把这种不是直接依赖主键,而是依赖非主键字段的依赖关系称之为传递依赖。

举例:讲师代课表

ID(P)

讲师

性别

教室

班级

时间

开始

结束

1

张三

204

Java基础

30天

2018-01-01

2018-01-31

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

以上表设计方案中,性别依赖讲师存在,讲师依赖主键;教室依赖班级,而班级依赖主键。性别和教室都存在传递依赖。

解决方案:将存在传递依赖的字段以及依赖字段本身单独取出,形成单独表,然后在需要对应的信息的时候,使用对应实体表的主键加进来。

讲师代课表

ID(P)

讲师ID

班级ID

时间

开始

结束

1

1

10

30天

2018-01-01

2018-01-31

2

2

20

 

 

 

 

 

 

 

 

 

讲师表

ID

讲师

性别

1

张三

班级表

ID

班级

教室

10

Java基础

201

讲师表中ID=讲师,同样班级表中ID=班级,因为讲师可能存在名称重名的,所以增加ID这个逻辑主键。

范式逆规范化

有时候在设计表的时候,如果一张表中有几个字段是需要从另外的表中去获取信息,理论上讲,的确可以获取到想要的数据,但是就是查询效率低一点,会可以的在某些表中,不去保存另外表的主键(逻辑主键),而是直接保存想要的数据信息,这样一来,在查询数据的时候,一张表可以直接提供数据,而不需要多表查询,但是会导致数据冗余增加,这个方式就是范式逆规范化。

举例:还是讲师代课表

ID(P)

讲师ID

班级ID

时间

开始

结束

1

张三

Java基础

30天

2018-01-01

2018-01-31

2

李四

Python基础

 

 

 

 

 

 

 

 

 

上面我们不存储讲师和班级ID,直接存储讲师名称和班级名称,这样我们就在一张表就可以获取查询讲师和班级信息。

所谓逆规范化就是磁盘的利用率和查询效率的博弈。总结,范式只需要了解1NF,2NF,3NF,可以锁第四范式以后限制条件越多,效率反而越低。