当前位置: 首页 > news >正文

【MySQL】数据库三大范式

目录

一. 什么是范式

二. 第一范式

三. 第二范式

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

 四. 第三范式


一. 什么是范式

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

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

第一范式(1NF)

第二范式(2NF)

第三范式(3NF)

巴斯-科德范式(BCNF)

第四范式(4NF)

第五范式(5NF)

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

二. 第一范式

第一范式的定义:

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

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

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

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

 总结:

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

三. 第二范式

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

名词解释:

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

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

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

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

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

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

在上图的设计的表中:

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

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

拿之前的反例图为例:

1. 数据冗余

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

 2. 更新异常

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

3.插入异常

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

4.删除异常

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

 四. 第三范式

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

反例演示:

 注意:

对于上面这张图大家可能会理解为,学号、姓名、年龄、性别依赖于id,而学院电话依赖于学院,那么此时不就是部分函数依赖的现象吗,此时就不满足第二范式了呀?
解释:
对于第二范式的例子,我们需要通过学生学号确定学生信息,通过课程来确定学分,此时通过学生学号+课程来标识出当前学生这一科的成绩,此时是需要通过学生学号和课程来作为复合主键标识一个学生某门课程的成绩的,所以不同的信息依赖于不同的主键列,这时候才是部分函数依赖的情况

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

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


 

上图表:

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

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

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


http://www.xdnf.cn/news/474211.html

相关文章:

  • 【Java微服务组件】分布式协调P1-数据共享中心简单设计与实现
  • 【开源Agent框架】CAMEL:角色扮演+任务分解
  • QT6 源(101)篇一:阅读与注释 QPlainTextEdit,其继承于QAbstractScrollArea,属性学习与测试
  • AI Agent开发第67课-彻底消除RAG知识库幻觉(1)-文档分块全技巧
  • 2025ICPC陕西省赛题解
  • 以项目的方式学QT开发C++(一)——超详细讲解(120000多字详细讲解,涵盖qt大量知识)逐步更新!
  • 表记录的检索
  • 强化学习入门:马尔科夫奖励过程
  • 小白学编程之——数据库如何性能优化
  • c语言 写一个五子棋
  • 服务器选购指南:从零开始了解服务器
  • 【GitHub加速地址】
  • 比亚迪跨界降维打击!将正式宣布跨界,进入两三轮电动车电池市场
  • vue插槽的实例详解
  • 缺乏需求优先级划分时,如何合理分配资源?
  • python-修改图片背景色
  • java分布式服务的高可用处理
  • 优化算法加速深度学习模型训练
  • 《棒球百科》市运会是什么级别的比赛·棒球1号位
  • 一种改进DEIM(CVPR2025)的简单示例
  • 前端学习:align-items 和 justify-content 概念和区别
  • 图片通过滑块小图切换大图放大镜效果显示
  • SDC命令详解:使用get_pins命令进行查询
  • Vue.js---避免无限递归循环 调度执行
  • Weblogic SSRF漏洞复现(CVE-2014-4210)【vulhub靶场】
  • 黑马Java基础笔记-11
  • 深度学习之用CelebA_Spoof数据集搭建一个活体检测-训练好的模型用MNN来推理
  • Turbo C++
  • 数据驱动下的具身智能进化范式
  • 专项智能练习(定义判断)