【MySQL】数据库三大范式

目录

[一. 什么是范式](#一. 什么是范式)

[二. 第一范式](#二. 第一范式)

[三. 第二范式](#三. 第二范式)

不满足第二范式时可能出现的问题

[四. 第三范式](#四. 第三范式)


一. 什么是范式

在数据库中范式其实就是一组规则,在我们设计数据库的时候,需要遵守不同的规则要求,设计出合理的关系型数据库,对于不同的规范要求就被称为不同的范式

关系型数据库的范式分类:

第一范式(1NF)

第二范式(2NF)

第三范式(3NF)

巴斯-科德范式(BCNF)

第四范式(4NF)

第五范式(5NF)

范式越高对于数据库数据冗余越小,对于实际应用中,数据库的设计通常只需要满足第三范式的要求即可。

二. 第一范式

第一范式的定义:

数据库表中的每一列都是不可分割的原子数据项

在关系型数据库的设计中,满足第一范式是对关系型数据库的基本要求,不满足第一范式的数据库不是关系型数据库

不可分割的原子数据项:只要可以用MySQL中的基本数据类型描述的列就是不可分割的原子数据项

我们接下来看一个不满足第一范式的反例:
那么此时的学校就不能被称为是一个**不可分割的原子数据项,**学校此时可以说是一个对象,还可以继续进行拆分,所以不满足第一范式的要求,那么此时我们应该将学校进行拆分来满足第一范式的要求:

总结:

在关系型数据库中,只要每一列都可以使用基本数据类型进行表示,那么此时就满足第一范式的要求

三. 第二范式

第二范式是值在满足第一范式(每一列都是不可分割的原子数据项 )的基础上,并且不存在非关键字段任意候选键 的**部分函数依赖,**此时是在表中存在定义了复合主键的情况下。

名词解释:

非关键字段:即不被主键外键 或者唯一键约束的列

候选键:可以唯一表示一行数据的列或者列的组合,可以从候选键中选一个或者多个当做表的主键

部分函数依赖:见下图解释

上图的学生表此时就不满足第二范式的要求:

  • 上图的学生表中其实是使用学号+课程名定义复合主键来标识一个学生某门课程的成绩,此时就是这张表的作用。
  • 但是学生的信息是通过学号来确定的,学生的信息和课程名没有关系,所以此时的学生信息只依赖学号,不依赖课程名。学分是由课程来确定的,此时的学分只依赖课程名,不依赖学号(那么此时就出现了部分依赖的情况)不满足第二范式的要求

那么下面我们就来定义一个满足第二范式的表:

在上图的设计的表中:

  1. 学生表中,学号、姓名、年龄、性别都依赖于id列
  2. 课程表中,课程名、学分都依赖于id列
  3. 成绩表中,成绩依赖于学生id和课程id
  4. 对于每个表来说都不会出现部分函数依赖的现象,当一张表的主键只有一列时天然满足第二范式

不满足第二范式时可能出现的问题

拿之前的反例图为例:

  1. 数据冗余

学生的姓名、年龄、性别和课程的学分在每条记录中重复出现,会造成大量的数据冗余(比如说张三不仅学了MySQL还学了Python和Java,那么此时就会多出2条记录,多出的两条记录就会重复包含姓名、年龄、性别、课程名、学分这些冗余信息)

  1. 更新异常

假设现在需要调整MySQL的学分,此时需要一个一个去更新每条学生信息中包含的学分信息,但是一旦更改时中断没有及时更新全部,那么此时就会造成表中不同学生的MySQL学分不同,出现数据不一致的问题

3.插入异常

此时当前表中,成绩与每一门课和学生都有对应的关系,此时只有学生参加了考试取得成绩才会生成记录,库中才会有课程的学分,但是学生取得成绩之前,这门课在数据库中就不存在,此时插入的成绩数据就是空没有任何意义

4.删除异常

此时将毕业学生的考试数据都进行删除,此时课程和学分的信息也会被删除,导致数据库中没有这门课和学分信息

四. 第三范式

第三范式即在满足第二范式的基础上,并且不存在非关键字段任意候选键的传递依赖

反例演示:

注意:

对于上面这张图大家可能会理解为,学号、姓名、年龄、性别依赖于id,而学院电话依赖于学院,那么此时不就是部分函数依赖 的现象吗,此时就不满足第二范式了呀?

解释:

对于第二范式的例子,我们需要通过学生学号确定学生信息,通过课程来确定学分,此时通过学生学号+课程 来标识出当前学生这一科的成绩,此时是需要通过学生学号和课程来作为复合主键 标识一个学生某门课程的成绩的,所以不同的信息依赖于不同的主键列,这时候才是部分函数依赖 的情况

但是上图我们只需要获取学生的信息,所以只定义id列为主键来标识某一个学生信息即可,但是现在可以看出学生的学号、姓名、年龄、性别和主键id是关联的,学院电话和学院是关联的(学院电话依赖的是非关键字段 ),此时通过学生id可以找到学生信息,学生信息中包含着学院名,学院名又有着自己的电话,此时就存在一种信息传递现象

这种现象称为传递依赖,所以当前的表不满足第三范式但是满足第二范式

此时我们需要将学院信息拆分出来定义学院表,学生表和学院表做关联:

上图表:

学生表中:学号、姓名、年龄、性别、学院id依赖于id

学院表中:学院、学院电话依赖于id

此时就不会出现传递依赖的情况,满足第三范式的要求


相关推荐
未来之窗软件服务44 分钟前
solidwors插件 开发————仙盟创梦IDE
前端·javascript·数据库·ide·仙盟创梦ide
yc_12241 小时前
SqlHelper 实现类,支持多数据库,提供异步操作、自动重试、事务、存储过程、分页、缓存等功能。
数据库·c#
Leo.yuan2 小时前
基于地图的数据可视化:解锁地理数据的真正价值
大数据·数据库·信息可视化·数据挖掘·数据分析
好吃的肘子2 小时前
MongoDB入门
数据库·mongodb
noravinsc2 小时前
人大金仓数据库 与django结合
数据库·python·django
代码配咖啡3 小时前
《Navicat之外的新选择:实测支持国产数据库的SQLynx核心功能解析》
数据库
懒大王爱吃狼3 小时前
怎么使用python进行PostgreSQL 数据库连接?
数据库·python·postgresql
时序数据说3 小时前
IoTDB集群的一键启停功能详解
大数据·数据库·开源·时序数据库·iotdb
小叶子来了啊3 小时前
信息系统运行管理员:临阵磨枪版
运维·服务器·数据库
数据库幼崽4 小时前
MySQL 8.0 OCP 1Z0-908 131-140题
数据库·mysql·ocp