CategoryResourceRepost/极客时间专栏/SQL必知必会/第二章:SQL性能优化篇/21丨范式设计:数据表的范式有哪些,3NF指的是什么?.md
louzefeng d3828a7aee mod
2024-07-11 05:50:32 +00:00

114 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<audio id="audio" title="21丨范式设计数据表的范式有哪些3NF指的是什么" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/d7/96/d7e62e9125d028405ee15ce3f8a12796.mp3"></audio>
在日常工作中,我们都需要遵守一定的规范,比如签到打卡、审批流程等,这些规范虽然有一定的约束感,却是非常有必要的,这样可以保证正确性和严谨性,但有些情况下,约束反而会带来效率的下降,比如一个可以直接操作的任务,却需要通过重重审批才能执行。
实际上,数据表的设计和工作流程的设计很像,我们既需要规范性,也要考虑到执行时的方便性。
今天,我来讲解一下数据表的设计范式。范式是数据表设计的基本原则,又很容易被忽略。很多时候,当数据库运行了一段时间之后,我们才发现数据表设计得有问题。重新调整数据表的结构,就需要做数据迁移,还有可能影响程序的业务逻辑,以及网站正常的访问。所以在开始设置数据库的时候,我们就需要重视数据表的设计。
今天的课程你需要掌握以下几个方面的内容:
1. 数据库的设计范式都有哪些?
1. 数据表的键都有哪些?
1. 1NF、2NF和3NF指的是什么
## 数据库的设计范式都包括哪些
我们在设计关系型数据库模型的时候需要对关系内部各个属性之间联系的合理化程度进行定义这就有了不同等级的规范要求这些规范要求被称为范式NF。你可以把范式理解为一张数据表的设计结构需要满足的某种设计标准的级别。
目前关系型数据库一共有6种范式按照范式级别从低到高分别是1NF第一范式、2NF第二范式、3NF第三范式、BCNF巴斯-科德范式、4NF第四范式和5NF第五范式又叫做完美范式
数据库的范式设计越高阶冗余度就越低同时高阶的范式一定符合低阶范式的要求比如满足2NF的一定满足1NF满足3NF的一定满足2NF依次类推。
你可能会问,这么多范式是不是都要掌握呢?
一般来说数据表的设计应尽量满足3NF。但也不绝对有时候为了提高某些查询性能我们还需要破坏范式规则也就是反规范化。
<img src="https://static001.geekbang.org/resource/image/42/9b/4299e5030169710d5b1d29fd0729879b.jpg" alt="">
## 数据表中的那些键
范式的定义会使用到主键和候选键因为主键和候选键可以唯一标识元组数据库中的键Key由一个或者多个属性组成。我总结了下数据表中常用的几种键和属性的定义
- 超键:能唯一标识元组的属性集叫做超键。
- 候选键:如果超键不包括多余的属性,那么这个超键就是候选键。
- 主键:用户可以从候选键中选择一个作为主键。
- 外键如果数据表R1中的某属性集不是R1的主键而是另一个数据表R2的主键那么这个属性集就是数据表R1的外键。
- 主属性:包含在任一候选键中的属性称为主属性。
- 非主属性:与主属性相对,指的是不包含在任何一个候选键中的属性。
通常,我们也将候选键称之为“码”,把主键也称为“主码”。因为键可能是由多个属性组成的,针对单个属性,我们还可以用主属性和非主属性来进行区分。
看到上面的描述你可能还是有点懵,我举个简单的例子。
我们之前用过NBA的球员表player和球队表team。这里我可以把球员表定义为包含球员编号、姓名、身份证号、年龄和球队编号球队表包含球队编号、主教练和球队所在地。
对于球员表来说,超键就是包括球员编号或者身份证号的任意组合,比如(球员编号)(球员编号,姓名)(身份证号,年龄)等。
候选键就是最小的超键,对于球员表来说,候选键就是(球员编号)或者(身份证号)。
主键是我们自己选定,也就是从候选键中选择一个,比如(球员编号)。
外键就是球员表中的球队编号。
在player表中主属性是球员编号身份证号其他的属性姓名年龄球队编号都是非主属性。
## 从1NF到3NF
了解了数据表中的4种键之后我们再来看下1NF、2NF和3NFBCNF我们放在后面讲。
**1NF指的是数据库表中的任何属性都是原子性的不可再分**。这很好理解我们在设计某个字段的时候对于字段X来说就不能把字段X拆分成字段X-1和字段X-2。事实上任何的DBMS都会满足第一范式的要求不会将字段进行拆分。
**2NF指的数据表里的非主属性都要和这个数据表的候选键有完全依赖关系**。所谓完全依赖不同于部分依赖,也就是不能仅依赖候选键的一部分属性,而必须依赖全部属性。
这里我举一个没有满足2NF的例子比如说我们设计一张球员比赛表player_game里面包含球员编号、姓名、年龄、比赛编号、比赛时间和比赛场地等属性这里候选键和主键都为球员编号比赛编号我们可以通过候选键来决定如下的关系
(球员编号, 比赛编号) → (姓名, 年龄, 比赛时间, 比赛场地,得分)
上面这个关系说明球员编号和比赛编号的组合决定了球员的姓名、年龄、比赛时间、比赛地点和该比赛的得分数据。
但是这个数据表不满足第二范式,因为数据表中的字段之间还存在着如下的对应关系:
(球员编号) → (姓名,年龄)
(比赛编号) → (比赛时间, 比赛场地)
也就是说候选键中的某个字段决定了非主属性。你也可以理解为,对于非主属性来说,并非完全依赖候选键。这样会产生怎样的问题呢?
1. 数据冗余如果一个球员可以参加m场比赛那么球员的姓名和年龄就重复了m-1次。一个比赛也可能会有n个球员参加比赛的时间和地点就重复了n-1次。
1. 插入异常:如果我们想要添加一场新的比赛,但是这时还没有确定参加的球员都有谁,那么就没法插入。
1. 删除异常:如果我要删除某个球员编号,如果没有单独保存比赛表的话,就会同时把比赛信息删除掉。
1. 更新异常:如果我们调整了某个比赛的时间,那么数据表中所有这个比赛的时间都需要进行调整,否则就会出现一场比赛时间不同的情况。
为了避免出现上述的情况,我们可以把球员比赛表设计为下面的三张表。
球员player表包含球员编号、姓名和年龄等属性比赛game表包含比赛编号、比赛时间和比赛场地等属性球员比赛关系player_game表包含球员编号、比赛编号和得分等属性。
这样的话每张数据表都符合第二范式也就避免了异常情况的发生。某种程度上2NF是对1NF原子性的升级。1NF告诉我们字段属性需要是原子性的而2NF告诉我们一张表就是一个独立的对象也就是说一张表只表达一个意思。
**3NF在满足2NF的同时对任何非主属性都不传递依赖于候选键**。也就是说不能存在非主属性 A 依赖于非主属性 B非主属性 B 依赖于候选键的情况。
我们用球员player表举例子这张表包含的属性包括球员编号、姓名、球队名称和球队主教练。现在我们把属性之间的依赖关系画出来如下图所示
<img src="https://static001.geekbang.org/resource/image/42/33/4286e4c955589ab7145ee36ab135b933.jpg" alt=""><br>
你能看到球员编号决定了球队名称同时球队名称决定了球队主教练非主属性球队主教练就会传递依赖于球员编号因此不符合3NF的要求。
如果要达到3NF的要求需要把数据表拆成下面这样
球员表的属性包括球员编号、姓名和球队名称;球队表的属性包括球队名称、球队主教练。
我再总结一下1NF需要保证表中每个属性都保持原子性2NF需要保证表中的非主属性与候选键完全依赖3NF需要保证表中的非主属性与候选键不存在传递依赖。
## 总结
我们今天讲解了数据表设计的三种范式。关系型数据库的设计都是基于关系模型的在关系模型中存在着4种键这些键的核心作用就是标识。
在这些概念的基础上我又讲了1NF2NF和3NF。我们经常会与这三种范式打交道利用它们建立冗余度小、结构合理的数据库。
有一点需要注意的是,这些范式只是提出了设计的标准,实际上设计数据表时,未必要符合这些原则。一方面是因为这些范式本身存在一些问题,可能会带来插入,更新,删除等的异常情况(这些会在下一讲举例说明),另一方面,它们也可能降低会查询的效率。这是为什么呢?因为范式等级越高,设计出来的数据表就越多,进行数据查询的时候就可能需要关联多张表,从而影响查询效率。
<img src="https://static001.geekbang.org/resource/image/e7/11/e775113e733020a7810196afd4f58711.jpg" alt=""><br>
2NF和3NF相对容易混淆根据今天的内容你能说下这两个范式之间的区别吗另外如果我们现在有一张学生选课表包含的属性有学号、姓名、课程名称、分数、系别和系主任如果要改成符合3NF要求的设计需要怎么修改呢
欢迎你在评论区写下你的答案,也欢迎把这篇文章分享给你的朋友或者同事,一起来交流。