首页 > 数据库 >Mysql - 什么是三大范式(通俗详解)

Mysql - 什么是三大范式(通俗详解)

时间:2024-04-14 19:57:12浏览次数:16  
标签:范式 课程名称 002 001 Mysql 90 主键 三大

Mysql - 什么是三大范式(通俗详解)

高月之风 高月之风 关于数据的一切我都喜欢。   218 人赞同了该文章 ​ 展开目录  
Hello~我是高月!我将会在这篇文章中用通俗易懂的话为你简单说明 什么是 Mysql 的三大范式。如果喜欢这篇文章,请点赞、关注、收藏哦~

1. 简介

三大范式是 Mysql 数据库设计表结构所遵循的规范和指导方法,目的是为了减少冗余,建立结构合理的数据库,从而提高数据存储和使用的性能。

三大范式之间是具有依赖关系的,比如第二范式是在第一范式的基础上建设的、第三范式是在第二范式的基础上建设的。

当然 Mysql 数据库的范式不止三大范式,除了三大范式,还有巴斯-科德范式(BCNF)、第四范式(4NF)、第五范式(5NF,又称“完美范式")。

而本篇文章,我们只介绍范式中常用的三大范式。

虽然,遵循范式能使我们的数据库结构更合理,但是也不是一成不变的,偶尔我们也要学会在范式的基础,根据实际应用场景,作出相应的变通。

2. 第一范式 - 1NF

遵循原子性。即,表中字段的数据,不可以再拆分。

先看一个不符合第一范式的表结构,如下:

员工编码姓名年龄
001 销售部小张 28
002 运营部小黄 25
003 技术部小高 22

在这一个表中的,姓名 字段下的数据是可以再进行拆分的,因此它不符合第一范式,那怎么样才符合第一范式呢?如下:

员工编码部门姓名年龄
001 销售部 小张 28
002 运营部 小黄 25
003 技术部 小高 22

那是否遵循第一范式就一定是好的呢?如下:

员工编码姓名地址
001 小张 江西省南昌市东湖区
002 小黄 广东省佛山市禅城区
003 小高 湖北省武汉市新洲区

通过观察上述表结构,我们发现,地址是可以再进一步拆分的,比如:

员工编码姓名
001 小张 江西省 南昌市 东湖区
002 小黄 广东省 佛山市 禅城区
003 小高 湖北省 武汉市 新洲区

虽然拆分后,看上去更符合第一范式了,但是如果项目就只需要我们输出一个完整地址呢?那明显是表在没拆分的时候会更好用。

所以范式只是给了我们一个参考,我们更多的是要根据项目实际情况设计表结构。

3. 第二范式 - 2NF

在满足第一范式的情况下,遵循唯一性,消除部分依赖。即,表中任意一个主键或任意一组联合主键,可以确定除该主键外的所有的非主键值。

再通俗点讲就是,一个表只能描述一件事情。

我们用一个经典案例进行解析。

学号姓名年龄课程名称成绩学分
001 小张 28 语文 90 3
001 小张 28 数学 90 2
002 小黄 25 语文 90 3
002 小黄 25 语文 90 3
003 小高 22 数学 90 2

我们先分析一下表结构。

1. 假设学号是表中的唯一主键,那由学号就可以确定姓名和年龄了,但是却不能确定课程名称和成绩。

2. 假设课程名称是表中的唯一主键,那由课程名称就可以确定学分了,但是却不能确定姓名、年龄和成绩。

3. 虽然通过学号和课程名称的联合主键,可以确定除联合主键外的所有的非主键值,但是基于上述两个假设,也不符合第二范式的要求。

 

那我们应该如何调整表结构,让它能复合第二范式的要求呢?

我们可以基于上述的三种主键的可能,拆分成 3 张表,保证一张表只描述一件事情。

1. 学生表 - 学号做主键

学号姓名年龄
001 小张 28
002 小黄 25
003 小高 22

2. 课程表 - 课程名称做主键

课程名称学分
语文 3
数学 2

3. 成绩表 - 学号和课程名称做联合主键

学号课程名称成绩
001 语文 90
001 数学 90
002 语文 90
002 语文 90
003 数学 90

 

这时候我们可能会想,为什么我们就要遵循第二范式呢?不遵循第二范式会造成什么样的后果呢?

1. 造成整表的数据冗余。

如,学生表,可能我就只有2个学生,每个学生都有许多的信息,比如,年龄、性别、身高、住址......如果与课程信息放到同一张表中,可能每个学生有3门课程,那数据总条数就会变成6条了。但是通过拆分,学生表我们只需要存储 2 条学生信息,课程表只需要存储 3 条课程信息,成绩表就只需保留学号、课程名称和成绩字段。

2. 更新数据不方便。

假设,课程的学分发生了变更,那我们就需要把整表关于该课程的学分都要更新一次,但如果我们拆分出课程表,那我们就只需要把课程表中的课程信息更新就行。

3. 插入数据不方便或产生异常。

① 假设主键是学号或课程名称,我们新增了某个课程,需要把数据插入到表中,这时,可能只有部分人有选修这门课程,那我们插入数据的时候还要规定给哪些人插入对应的课程信息,同时可能由于成绩还没有,我们需要对成绩置空,后续有成绩后还得重新更新一遍。

② 假设主键是学号和课程名称的联合主键。同样也是新增了某课程,但是暂时没有人选修这门课,缺少了学号主键字段数据,会导致课程信息无法插入。

4. 第三范式 - 3NF

在满足第二范式的情况下,消除传递依赖。即,在任一主键都可以确定所有非主键字段值的情况下,不能存在某非主键字段 A 可以获取 某非主键字段 B。

仍然用一个经典例子来解析

学号姓名班级班主任
001 小黄 一年级(1)班 高老师

这个表中,学号是主键,它可以唯一确定姓名、班级、班主任,符合了第二范式,但是在非主键字段中,我们也可以通过班级推导出该班级的班主任,所以它是不符合第三范式的。

那怎么设计表结构,才是符合第三范式的呢?

1. 学生表

学号姓名班级
001 小黄 一年级(1)班

2. 班级表

班级班主任
一年级(1)班 高老师

通过把班级与班主任的映射关系另外做成一张映射表,我们就成功地消除了表中的传递依赖了。

总结

不知道读者们有没有发现,以上所介绍的范式的最终目的都是为了减少我们的工作量呢?所以说,尽管范式是一种很好的指导规范,但在实际应用中,我们也不需要太局限在范式中,更多的是应该从项目中出发,设计出合理的表结构。

以下是本篇三范式的简单总结:

  • 第一范式(1 NF):字段不可再拆分。
  • 第二范式(2 NF):表中任意一个主键或任意一组联合主键,可以确定除该主键外的所有的非主键值。
  • 第三范式(3 NF):在任一主键都可以确定所有非主键字段值的情况下,不能存在某非主键字段 A 可以获取 某非主键字段 B。

文章到这里就结束啦,如果喜欢这篇文章,请点赞、关注、收藏哦!你的点赞和关注就是我持续创作的动力!

文章有误之处欢迎评论区评论指出~

如果你有想了解 Mysql 的相关内容,可以到评论区留言,我会持续输出相关文章内容的~

标签:范式,课程名称,002,001,Mysql,90,主键,三大
From: https://www.cnblogs.com/sexintercourse/p/18134573

相关文章

  • 如何解决node.js运行mysql报错?
    首先检查mysql客户端的密码是否正确正确后提示我没有安装mysql模板 在文件目录终端下输入cnpminstall-gmysql进行安装这时候运行还是显示错误上网搜了一下说是登录数据库的客户端跟mysql8.0不兼容了,mysql8.0密码认证采用了新的密码格式[解决方法]打开命令管理器进入m......
  • MySQL 函数
    汇总函数rolluprollup是SQL关键字,在MySQL中得用withrollup。它是groupby子句的扩展,用于统计后增加一行汇总数据。举例,现有库存表,我们按仓库名称分组,统计每个仓库的产品总量,最后来一个汇总。mysql>SELECT*FROMinventory;+----+---------------+---------+----------......
  • 在centos7下面,安装mysql,并设置 用户名为henry
    好的,以下是在CentOS7下安装MySQL并完成你所要求的操作的详细步骤:1.**安装MySQL**:首先,使用`yum`包管理器安装MySQL:sudoyuminstallmysql-server 2.**启动MySQL服务**:安装完成后,启动MySQL服务:sudosystemctlstartmysqld 3.**设置MySQL开机自启......
  • mysql部署MGB
    基础环境node0:192.168.110.50 -->master节点node1:192.168.110.60node2:192.168.110.70MySQL版本->MySQL8.0.36在每台电脑上配置host名cat>/etc/hosts<<-'EOF'192.168.31.230n0192.168.31.231n1192.168.31.232n2EOF修改对应主机的主机名hostnamectlset......
  • MYSQL 主从同步失败:Slave_SQL_Running: No
    SHOWSLAVESTATUS\G;显示Slave_SQL_Running:No 解决方法:从主服务器查询:  SHOWMASTERSTATUS在从服务器上:changemastertomaster_host='169.254.60.151', #主库的IP地址master_user='slave', #在主库上创建的复制账号master_password='???????',......
  • Docker mysql 配置文件读取失败 [Warning] World-writable config file '/etc/mysql/c
    这个警告表明MySQL正在忽略/etc/mysql/conf.d/my.cnf这个配置文件,因为它被设置为了全世界可写。这个警告是基于安全性的考虑。当配置文件被设置为全世界可写时,任何人都可以修改它,这可能会导致安全风险,因为恶意用户可以更改MySQL的配置,从而影响数据库的行为和安全性。为了......
  • MySQL 8 显示错误代码2058
    在使用mysql-uroot-P3307-proot和SQLyong连接MySQL时报错1.在MySQL8.3CommandLineClient登录点击查看代码Enterpassword:****WelcometotheMySQLmonitor.Commandsendwith;or\g.YourMySQLconnectionidis14Serverversion:8.3.0MySQLCommunitySer......
  • MySQL-09-mysql 存储过程入门介绍
    拓展阅读MySQL00ViewMySQL01Rulermysql日常开发规范MySQL02truncatetable与delete清空表的区别和坑MySQL03Expression1ofORDERBYclauseisnotinSELECTlist,referencescolumnMySQL04EMOJI表情与UTF8MB4的故事MySQL05MySQL入门教程(MySQLtutor......
  • 如何找到相应程序的bin目录?(以MySQL为例)
    用win+R打开[运行]接着输入services.msc打开[服务] 在[名称]当中找到相应的程序,双击进入,如MySQL 就可以找到相应程序的bin目录啦......
  • FastAPI-MySQL-Cookie代码实现
    连接数据库fromsqlalchemyimportcreate_enginefromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemy.ormimportsessionmakerfromurllib.parseimportquote_pluspassword='123456'encoded_password=quote_plus(password)SQLALCHEM......