关系型数据库三大范式

文章目录

  • [一: 第一范式(1NF)列不可再分](#一: 第一范式(1NF)列不可再分)
  • [二: 第二范式(2NF)消除部分依赖](#二: 第二范式(2NF)消除部分依赖)
  • [三: 第三范式(3NF)消除传递依赖](#三: 第三范式(3NF)消除传递依赖)

文章作者:当战神遇到编程

文章专栏:MySQL

欢迎大家点赞👍评论📝收藏⭐文章



范式(Normal Form)是关系型数据库设计的规范,目的是:表设计得更合理,数据不重复,修改更方便。

一: 第一范式(1NF)列不可再分

核心要求:字段必须具有原子性(不可再分)

每一列 只能存一个值,不能存多个值。

不满足第一范式的例子

学号 姓名 班级名 学校信息
101 张三 Java一班 清华大学, 北京市海淀区, 010-8888

满足第一范式的例子(合格的表)

学号 姓名 班级名 学校名称 学校地址 学校电话
101 张三 Java一班 清华大学 北京市海淀区 010-8888

注意:

  • 数据库的"入场券": 第一范式是关系型数据库的最基本要求。如果不满足 1NF,则不能被称为真正的关系型数据库。
  • 原子性的标准: 原子性不是绝对的,而是根据业务需求 决定的。
    ○ 例如: 如果业务只需要显示全名,那么 姓名 就是原子的;但如果业务需要区分"姓"和"名",那么 姓名 就得拆分为 姓 和 名 两列。

二: 第二范式(2NF)消除部分依赖

核心定义:

在满足第一范式(1NF)的基础上,消除非主键字段对候选键的"部分函数依赖"。

1.必须要懂的底层概念 (术语拆解)

  • 候选键 (Candidate Key) vs 主键 (Primary Key)

    候选键 : 表中能唯一标识一行数据的列(或列组合)。

    主键 : 从候选键中选出来的"正职"班长。

    联合主键 : 由多个列共同组成的唯一主键。此时,单独的每一列只能叫"候选键",合在一起才叫"主键"。

  • 函数依赖

    完全函数依赖 : 必须通过整个主键 才能确定某个数据。(2NF 要求 )

    部分函数依赖 : 只通过主键中的一部分列 ,就能确定某个数据。 ( 2NF 禁止)

2.案例剖析

  • 这张表中使用学号 + 课程名定义联合主键来唯一标识一个学生某门课程的成绩
  • 这张表中学生姓名 依赖于学号 , 依赖于课程名 ,学分 依赖于课程名 , 依赖于学号,这两个非关键字段都不满足第二范式的核心定义

改正:拆成三个表

学生表

Id 学号 学生姓名 年龄 性别
1 10001 张三 18
2 10002 李四 19
3 10003 王五 18

课程表

Id 课程名 学分
1 MySQL 50
2 Java 60
3 C++ 60

成绩表

学生Id 课程Id 成绩
1 1 98
2 1 100
3 1 89
1 2 100
2 2 99
3 3 98

只有单列主键的表通常天然满足第二范式。

如果表没有满足第二范式,可能出现的问题有:

1.数据冗余 :学生的姓名,年龄学分都重复的出现,造成大量的数据冗余

  1. 更新异常 :假设需要调整MySQL的学分,就需要修改所有记录中关于MySQL的记录.如果部分记录更新失败,就会出现同一课程学分不一致的情况,表现为数据不一致

  2. 插入异常 :⽬前这样的设计,成绩与每⼀⻔课和学⽣都有对应关系,也就是说只有学⽣参加选修课程考试取得了成绩才能⽣成⼀条记录。当有⼀⻔新课还没有学⽣参加考试取得成绩之前,那么这⻔新课在数据库中是不存在的,因为成绩为空时记录没有意义。

  3. 删除异常:把毕业学⽣的考试数据全都删除,此时课程和学分的信息也会被删除掉,有可能导致⼀段时间内,数据库⾥没有某⻔课程和学分的信息。

三: 第三范式(3NF)消除传递依赖

定义:在满⾜第⼆范式的基础上,消除非主键字段对非主键字段的依赖(消除传递依赖)。

一、先理解什么叫传递依赖

如果存在:

sql 复制代码
主键 -> A -> B

说明:

  • A 依赖主键
  • B 又依赖 A

那么 B 就是间接依赖主键,这叫传递依赖。

举个例子:

学号 姓名 年龄 所属学院 学院地址 学院电话

存在传递依赖:学号-> 所在学院-> 学院电话 ,存在传递依赖的表不满足第三范式。

改正:只需要拆分成两张表。

1.学院表

学院编号 学院名 学院电话 学院地址

2.学生表

学号 姓名 年龄 学院编号

这样设计后,两张表中的非主键字段都直接依赖各自主键;学生表通过外键(学院编号)与学院表建立关联关系。

相关推荐
tjc199010051 小时前
SQL如何实现跨行数据比较分析_LEAD函数处理数据同步问题
jvm·数据库·python
HHHHH1010HHHHH2 小时前
golang如何实现可靠消息最终一致_golang可靠消息最终一致实现实战
jvm·数据库·python
独隅2 小时前
TLS协议深度解析:现代互联网的安全基石
数据库
m0_613856292 小时前
CSS如何实现复杂UI组件开发_结合BEM规范提升架构清晰度
jvm·数据库·python
阿维的博客日记2 小时前
隔离性和mvcc有什么关系吗
数据库·mysql·事务·mvcc·隔离性
qq_330037992 小时前
告别重复编码-Symfony自动化开发指南
jvm·数据库·python
腾科IT教育2 小时前
PostgreSQL 认证:PGCE 认证考什么?难度大吗?
数据库·postgresql·pgce·pgce认证·postgresql认证
能年玲奈喝榴莲牛奶2 小时前
国产数据库免费认证
数据库·大学生·考证·数据库认证·免费证书