史上最简单的 MySQL 教程(十九)「范式」

温馨提示:本系列博文已经同步到 GitHub,地址为「mysql-tutorial」,欢迎感兴趣的童鞋StarFork,纠错。

范式

范式:Normal Farmat是为了解决数据的存储和优化问题

在数据存储之后,凡是能够通过关系寻找出来的数据,坚决不再重复存储,范式的终极目标是减少数据冗余。

范式是一种分层结构的规范,共 6 层,分别为1NF2NF3NF4NF5NF6NF,每一层都比上一层严格,若要满足下一层范式,其前提是先满足上一层范式。其中,1NF是最底层的范式,6NF为最高层的范式,也最严格。

MySQL 数据库属于关系型数据库,其存储数据的时候有些浪费空间,但也致力于节省空间,这就与范式想要解决的问题不谋而合,因此在设计数据库的时候,大都会利用范式来指导设计。但是数据库不单是要解决存储空间的问题,还要保证效率的问题,而范式只为解决存储空间的问题,所以数据库的设计又不能完全按照范式的要求来实现,因此在一般情况下,只需要满足前三种范式即可。

此外,咱们需要知道:范式在数据库的设计中是有指导意义的,但不是强制规范

1NF

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

例如,咱们设计一个「学校假期时间表」,如下所示:

表 1:学校假期时间表

ID(P)

学校名称

起始日期,结束日期

1

哈尔滨工业大学

20170625,20170903

2

浙江大学

20170630,20170901

观察上表,咱们会发现表1的设计并没有什么问题,但是如果需求是查询各学校开始放假的日期呢?那显然上表的设计并不满足1NF,数据不具有原子性。对于此类问题,解决的方案就是将表1进行拆分:

表 2:拆分后的表 1

ID(P)

学校名称

起始日期

结束日期

1

哈尔滨工业大学

20170625

20170903

2

浙江大学

20170630

20170901

2NF

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

例如,咱们设计一个「教室授课表」,如下所示:

表 3:教室授课表

教师(P)

性别

课程

授课地点(P)

许仙

《如何追到心爱的女孩》

杭州西湖

白娘子

《论女人的恋爱修养》

雷峰塔

白娘子

《如何打赢与和尚之间的持久战》

金山寺

观察上表,咱们会发现:教师不能作为独立的主键,需要与授课地点相结合才能作为主键(复合主键,每个教师的某个课程只能在固定的地点上),其中性别依赖于具体的教师,而课程依赖于授课地点,这就出现了表的字段依赖于部分主键的问题,从而导致不满足第二范式。

  • 解决方案 1:将教师和性别,课程和授课地点,分成两张单独的表;
  • 解决方案 2:取消复合主键,使用逻辑主键。

在此,咱们采用 方案 2 的解决方法,即取消复合主键,使用逻辑主键。

ID(P)

教师

性别

课程

授课地点

1

许仙

《如何追到心爱的女孩》

杭州西湖

2

白娘子

《论女人的恋爱修养》

雷峰塔

3

白娘子

《如何打赢与和尚之间的持久战》

金山寺

3NF

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

以上述的添加逻辑主键后的 表3 为例:

ID(P)

教师

性别

课程

授课地点

1

许仙

《如何追到心爱的女孩》

杭州西湖

2

白娘子

《论女人的恋爱修养》

雷峰塔

3

白娘子

《如何打赢与和尚之间的持久战》

金山寺

在以上表的设计中,性别依赖教师,教师依赖主键;课程依赖授课地点,授课地点依赖主键,因此性别和课程都存在传递依赖的问题。

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

表 4:教师表

TEACHER_ID(P)

教师

性别

1

许仙

2

白娘子

3

白娘子

表 5:授课地点表

ADDRESS_ID(P)

课程

授课地点

1

《如何追到心爱的女孩》

杭州西湖

2

《论女人的恋爱修养》

雷峰塔

3

《如何打赢与和尚之间的持久战》

金山寺

表 6:进行处理后的表

ID(P)

TEACHER_ID

ADDRESS_ID

1

1

1

2

2

2

3

3

3

在观察上述 表 4表 5,咱们会发现TEACHER_ID等价于教师ADDRESS_ID等价于授课地点,因此其逻辑主键并没有什么实际的限制意义,咱们只需要看其具体代表的业务主键即可。咱们之所以使用逻辑主键,是因为:逻辑主键可以实现自动增长,并且数字传递比较方便,而且有利于节省空间

逆规范化

在某些特定的环境中(例如淘宝数据库),在设计表的时候,如果一张表中有几个字段是需要从另外的表中去获取数据,理论上讲,的确可以获得想要的数据,但是相对来说,其效率低会一点。此时为了提高查询效率,咱们会刻意的在某些表中,不去保存另外一张表的主键(逻辑主键),而是直接保存想要存储的数据信息,这样的话,在查询数据的时候,这张表就可以直接提供咱们想要的数据,而不需要多表查询,但是这样做会导致数据冗余。

实际上,逆规范化是磁盘利用率和效率之间的对抗


———— ☆☆☆ —— 返回 -> 史上最简单的 MySQL 教程 <- 目录 —— ☆☆☆ ————

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 zhuanlan_guanli@qq.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

3种提升云可扩展性的方法

如果只为计算资源付费,在Amazon云上部署业务可以实现高拓展性。但是要怎样利用Amazon的相关技术才能获得最好的可拓展性呢?

1719
来自专栏noteless

3.操作系统简单介绍 操作系统发展历史 批处理分时系统 操作系统是什么 操作系统对文件的抽象 进程 虚拟内存是什么 操作系统作用 操作系统功能

它是在人们使用计算机的过程中,为了管理硬件资源,提高性能提高资源利用率,而逐步地形成和完善起来的。

853
来自专栏技术文章

大神告诉你如何理解微服务框架

因为Martin Fowler和Chris Richardson两位大神的布道,及NetFlix和Amazon公司的实践,国内对于微服务的一些基础问题理解基本...

954
来自专栏Golang语言社区

游戏服务端究竟解决了什么问题?

当讨论到游戏服务端的时候,我们首先想到的会是什么?要回答这个问题,我们需要从游戏服务端的需求起源说起。

862
来自专栏服务端技术杂谈

牛B的网站怎么设计Feed流

大型互联网公司招聘的时候总是要求具备:高并发,高负载,大数据处理的能力。我们做了N多的系统项目,互联网产品,究竟哪些项目或者产品能够真正体现出高并发,高负载的处...

3876
来自专栏纯洁的微笑

微服务架构—服务降级

什么是服务降级?当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或...

692
来自专栏CSDN技术头条

如何创建一条可靠的实时数据流

数据的生命周期一般包含“生成、传输、消费”三个阶段。在有些场景下,我们需要将数据的变化快速地反馈到在线服务中,因此出现了实时数据流的概念。如何衡量数据流是否“可...

1818
来自专栏即时通讯技术

百万在线的美拍直播弹幕系统的实时推送技术实践之路1、内容概述2、关于作者3、起步——快速上线4、问题——上线后暴露的问题及解决方法5、升级1——实现高可用保障6、升级2——使用长连接替换短连接轮询方案

直播弹幕是直播系统的核心功能之一。如何迅速作出一个有很好扩展性的弹幕系统?如何应对业务迅速发展?相信很多工程师/架构师都有自己的想法。

542
来自专栏个人分享

分布式系统简介

  研究生阶段学习的分布式原理与泛型几乎忘完了,当初不怎么懂。。。现在工作中发现大数据技术的底层还是分布式系统,那么重新拾起,总结下~

872
来自专栏Java架构

看京东系统架构师如何让笨重的架构变得灵巧

1296

扫描关注云+社区