开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情
前言
上篇我们学习了MySQL中的数据库优化之设计规范。有兴趣的小伙伴可以阅读(MySQL中的数据库设计规范(二))。
下面我们继续学习MySQL中的数据库设计规范。
第一范式(1NF)
举例二
属性的原子性是主观的。
例如,雇员关系中雇员姓名应当使用一个(fullname),2个(firstname和lastname),3个(firstname,middlename和lastname)属性表示呢?这应该取决于应用程序。
如果应用程序需要分别处理雇员的姓名部分,比如用于搜索目的,则有必要把它们分开。否则,不需要。
第二范式(2NF)
表中字段不存在除额外的依赖关系。
举例一
成绩表(学号,课程号,成绩)关系中,(学号,课程号)可以决定成绩,但是学号不能决定成绩,课程号也不能决定成绩,所以(学号,课程号)-> 成绩就是完全依赖关系。
举例二
比赛表中包含字段球员编号,姓名,年龄,比赛编号,比赛时间和比赛场地等属性,这里候选键和主键都为(球员编号,比赛编号),我们可以通过候选键(或主键)来决定如下的关系:(球员编号,比赛编号)-> (姓名,年龄,比赛时间,比赛场地,得分)。但是这个数据表不满足第二范式,因为数据表中的字段之间还存在着如下的对应关系。
- (球员编号) -> (姓名,年龄)
- (比赛编号) -> (比赛时间,比赛场地)
对于非主属性来说,并非完全依赖候选键。这样会产生怎么样的问题呢?
- 数据冗余:如果一个球员可以参加m场比赛,那么球员的姓名和年龄就重复了m-1次。一个比赛也可能会有n个球员参加,比赛的时间和地点就重复了n-1次。
- 插入异常:如果我们想要添加一场新的比赛,但是这时还没有确定参加的球员都有谁,那么就没法插入。
- 删除异常:如果我要删除某个球员编号,如果没有单独保存比赛表的话,就会同时把比赛信息删除掉。
- 更新异常:如果我们调整了某个比赛的时间,那么数据表中所有这个比赛的时间都需要调整,否则就会出现一场比赛时间不同的情况。
为了避免上述的情况,我们可以把球员比赛表设计为下面的三张表。
表名 | 属性 |
---|---|
球员表 | 球员编号,姓名和年龄等属性 |
比赛表 | 比赛编号,比赛时间和比赛场地等属性 |
球员关系表 | 球员编号,比赛编号和得分等属性 |
这样的话,每张数据表都符合第二范式,也就避免了异常情况的发生。
1NF告诉我们字段属性需要是原子性的,而2NF告诉我们一张表就是一个独立的对象,一张表只表达一个意思。
今天先学到这里,明天继续。