梳理一下 mysql(或关系型数据库)中的第一、二、三、四范式,这是数据库设计中非常重要的规范化理论。
第一范式 (1nf:first normal form)
定义:字段具有原子性,不可再分。
数据表中每一列都必须是不可分割的最小数据单元。
每一行都应该是唯一的(通常通过主键来保证)。
✅ 举例:
不符合 1nf:
学生表 学号 姓名 联系方式 1 张三 1380000, 1391111
问题:联系方式有多个值,违反原子性。
符合 1nf:
学生表 学号 姓名 联系方式 1 张三 1380000 1 张三 1391111
第二范式 (2nf:second normal form)
定义:在 1nf 的基础上,要求每个非主属性完全依赖于主键,不能只依赖主键的一部分。
适用于 联合主键 的情况。
消除部分依赖。
✅ 举例:
不符合 2nf:
选课表 学号+课程号 (联合主键) 姓名 成绩 1+001 张三 95
问题:姓名只依赖学号,而不是依赖于 (学号+课程号) 这个整体主键。
符合 2nf(拆表):
学生表 学号 姓名 选课表 学号 课程号 成绩
第三范式 (3nf:third normal form)
定义:在 2nf 基础上,非主属性不依赖于其他非主属性(消除传递依赖)。
属性不能依赖于主键之外的属性。
✅ 举例:
不符合 3nf:
学生表 学号 姓名 系编号 系名称
问题:系名称依赖于系编号,而系编号又依赖学号(学号 → 系编号 → 系名称,产生传递依赖)。
符合 3nf(拆表):
学生表 学号 姓名 系编号 系别表 系编号 系名称
第四范式 (4nf:fourth normal form)
定义:在 3nf 基础上,要求多值依赖消除。
一张表中不应包含两个或多个相互独立的多对多关系。
✅ 举例:
不符合 4nf:
学生表 学号 爱好 擅长课程 1 足球 数学 1 足球 英语 1 篮球 数学 1 篮球 英语
问题:爱好与擅长课程之间是独立的多值依赖,导致大量冗余。
符合 4nf(拆表):
学生_爱好表 学号 爱好 学生_课程表 学号 擅长课程
总结
1nf:字段不可再分(原子性)
2nf:非主属性完全依赖主键(消除部分依赖)
3nf:非主属性不依赖于其他非主属性(消除传递依赖)
4nf:不允许一个表里有多个独立的多值依赖
👉 实际开发中:
3nf 已经能满足大部分场景;
4nf 更偏学术,业务里一般用到 3nf + 适当的反规范化(为了性能)。
👌 那我帮你整理一个 1nf ~ 4nf 对比表,方便快速理解和记忆:
数据库范式对比表
| 范式 | 要求 | 典型问题 | 示例(不符合) | 示例(符合) |
|---|---|---|---|---|
| 第一范式 (1nf) | 字段必须原子化,不可再分 | 字段中有多个值,违反原子性 | 联系方式: 1380000, 1391111 | 每条记录一条联系方式 |
| 第二范式 (2nf) | 在 1nf 基础上,非主属性必须完全依赖主键,不能部分依赖 | 联合主键时,非主属性只依赖其中一部分 | (学号+课程号) → 姓名 | 将姓名拆到“学生表” |
| 第三范式 (3nf) | 在 2nf 基础上,非主属性不能依赖其他非主属性(消除传递依赖) | 非主属性依赖另一个非主属性 | 学号 → 系编号 → 系名称 | 把“系编号-系名称”拆到“系别表” |
| 第四范式 (4nf) | 在 3nf 基础上,消除多值依赖(不能同时描述多个独立的多对多关系) | 一张表里既存储“爱好”,又存储“擅长课程” | 学号 → 爱好 和 学号 → 擅长课程 | 分成“学生_爱好表”和“学生_课程表” |
📌 记忆口诀:
1nf:字段原子化
2nf:消除部分依赖
3nf:消除传递依赖
4nf:消除多值依赖
画一个 范式演进示意图(从 1nf → 4nf,逐步拆表的过程)这样更直观。
画一个 1nf → 4nf 的演进示意图,用一个「学生」场景,逐步展示规范化的过程:
范式演进示意图
未规范化
学生表 学号 | 姓名 | 联系方式 | 系名称 | 爱好 | 擅长课程 1 | 张三 | 1380000,1391111 | 计算机系 | 足球 | 数学
问题:
联系方式不原子化(违反 1nf)
姓名只依赖学号,不依赖课程号(违反 2nf)
系名称依赖于系编号,而不是直接依赖学号(违反 3nf)
爱好和课程是独立的多值依赖(违反 4nf)
第一范式 (1nf)
解决字段不可再分 → 拆分联系方式
学生表 学号 | 姓名 | 联系方式 | 系编号 | 系名称 | 爱好 | 擅长课程 1 | 张三 | 1380000 | 01 | 计算机 | 足球 | 数学 1 | 张三 | 1391111 | 01 | 计算机 | 足球 | 数学
第二范式 (2nf)
解决部分依赖 → 拆分“学生”和“选课”
学生表 学号 | 姓名 | 系编号 选课表 学号 | 课程号 | 成绩
第三范式 (3nf)
解决传递依赖 → 把系名称单独拆表
学生表 学号 | 姓名 | 系编号 系别表 系编号 | 系名称 选课表 学号 | 课程号 | 成绩
第四范式 (4nf)
解决多值依赖 → 爱好、擅长课程单独拆表
学生表 学号 | 姓名 | 系编号 系别表 系编号 | 系名称 选课表 学号 | 课程号 | 成绩 学生_爱好表 学号 | 爱好 学生_课程表 学号 | 擅长课程
📌 最终结果:
每张表结构更清晰,避免冗余和异常(插入、更新、删除异常)。
实际项目中常用到 3nf,4nf 更多是学术或复杂业务场景。
总结
到此这篇关于后端mysql数据库四大范式的文章就介绍到这了,更多相关后端数据库四大范式内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论