浅谈mysql范式

247 阅读5分钟

范式:关系型数据库中,关于数据表设计的基本原则、规则。数据库的范式设计的越高阶,冗余度越低。在关系型数据库中,普遍是3NF、最高遵循BCNF。

  • 第一范式(1NF)
  • 第二范式(2NF)
  • 第三范式(3NF)
  • 巴斯范式(BCNF)
  • 第四范式(4NF)
  • 第五范式(5NF、完美范式)

QQ截图20220610212841.png

  1. 第一范式 第一范式确保数据表中每个字段值必须具有原子性,即数据表中每个字段的值为不可再拆分的最小数据单元。设计某个字段时,对于字段X来说,不能把字段X拆分为字段X-1和字段X-2。字段值的原子性是主观的。

  2. 第二范式 第二范式在第一范式的基础上,还要满足数据表里的每一条数据记录,都是可唯一标识的。而且所有非主键字段,都必须完全依赖主键,不能只依赖主键的一部分。如果知道主键的所有属性的值,就可以检索到任何元组(行)的任何属性的任何值。

举例1:成绩表(学号、课程号、成绩)关系中,(学号、课程号)可以决定成绩,但是学号不能决定成绩,课程号也不能决定成绩,所以(学号、课程号)→成绩就是完全依赖关系。 举例2:比赛表,里面包含球员编号、姓名、年龄、比赛编号、比赛时间和比赛场地等属性,候选键和主键(球员编号、比赛编号),可以通过候选键(或主键)来决定如下关系:

(球员编号,比赛编号) → (姓名,年龄,比赛时间,比赛场地,得分)

但是这个数据表中姓名、年龄只依赖于球员编号,比赛时间、比赛场地只依赖于比赛编号,不满足第二范式中所有非主键字段必须完全依赖主键,不能只依赖主键的一部分。

对于非主键字段来说,不完全依赖候选键,会产生如下问题:

  • 数据冗余:如果一个球员可以参加n场比赛,那么球员的姓名和年龄就重复了n-1次。
  • 插入异常:当添加一场新的比赛时,还没有确定参加的球员名单,那么就没法插入。
  • 删除异常:如果删除某个球员编号,没有单独保存比赛表的情况下,就会删除比赛信息。
  • 更行异常:调整某个比赛的时间,数据表中所有这场比赛的时间都需要进行调整,否则就会出现一场比赛时间不同的情况。 为了避免上述情况,可以把球员比赛表设计为下面三张表
表名字段名
球员表球员编号、姓名和年龄等属性
比赛表比赛编号、比赛时间和比赛场地等属性
球员比赛关系表球员编号、比赛编号和得分等属性

每张表均满足第二范式要求,避免异常情况发生

总结:1NF表明字段值需要是原子的,2NF表明一张表就是一个独立的对象,一张表只表达一个含义。2NF要求实体的属性完全依赖关键字,如果不存在完全依赖,那么这个属性和主键的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多关系。

  1. 第三范式 第三范式在第二范式的基础上,确保数据表中的每一个非主键字段都和主键字段直接相关,即要求数据表中的所有非主键字段不能依赖于其他非主键字段(比如不能存在非主键属性A依赖于非主键属性B,非主键属性B依赖于主键C,存在A→B→C的关系),简而言之,所有非主键属性之间不能有依赖关系,必须相互独立。

举例1:

部门信息表:每个部门都有部门编号、部门名称、部门简介等信息。

员工信息表:每个员工有员工编号、姓名、部门编号。列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。

倘若不存在部门信息表,根据第三范式也应该构建它,否则会有大量的数据冗余。

2NF和3NF通常概括为:“每个非主键属性依赖于主键,且依赖于整个主键,非主键字段都和主键字段直接相关”。

  1. 总结 1NF确保每个字段原子性,不可再拆;2NF确保每个字段和主键完全依赖,尤其在符合主键情况下,非主键部分不应该依赖于部分主键;3NF1确保每列和主键直接相关,而不是间接相关。
  • 优点:数据的标准化有助于消除数据库中的数据冗余,第三范式通常在性能、扩展性和数据完整想方面达到了最好的平衡。
  • 缺点:使用范式,可能降低查询效率。范式等级越高,设计出来的数据表就越多、越精细、数据的冗余度就越低,进行数据查询时可能需要关联多张表,代价昂贵,可能是一些索引策略无效。

范式只是提出了数据库设计的标准,实际设计数据表,未必一定要符合这些标准。开发中,为了性能和读取效率违反范式化原则,通过增加少量的冗余来提高数据库的读性能,减少关联查询,实现空间换取时间的目的。