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

数据库的第一、二、三范式分别解决了什么问题?一文详解

目录

第一范式:列的原子性

1.核心口号

2.解决的问题

3.反面教材(违反1NF)

第二范式:消除部分依赖

1.核心口号

2.解决的问题

3.反面教材(违反2NF)

第三范式:消除传递依赖

1.核心口号

2.解决的问题

3.反面教材(违反3NF)

总结与对比

面试必背口诀


在数据库设计的面试中,“范式”是一个绕不开的高频考点。很多开发者在实际工作中可能习惯“一把梭”,把所有字段塞进一张大表里,但到了面试现场或者处理复杂业务时,就会因为不懂范式而导致数据库设计冗余严重、维护困难。

简单来说,数据库范式就是一套“拆表规则”。它的核心目的只有一个:减少数据冗余,避免数据异常(插入、更新、删除异常)。

今天我们就通过具体的案例和表格,把第一、二、三范式彻底讲透。


第一范式:列的原子性

1.核心口号

“列不能再分。”

2.解决的问题

第一范式(1NF)是数据库设计的最基本要求。它要求表中的每一个字段都必须是不可分割的原子值。如果一个字段里存了“多个值”,就不符合1NF。

3.反面教材(违反1NF)

假设我们有一张学生联系表:

学号姓名联系方式
001张三13800001234, 010-88888888
002李四13900005678

问题分析:
“联系方式”这一列里,张三既有手机号又有座机号,它们被逗号分隔存在同一个格子里。

  • 查询困难:如果你想查“所有有座机号的学生”,SQL写起来会非常麻烦。
  • 数据混乱:你无法单独约束“手机号”必须是11位数字。

修正方案(符合1NF):
将“联系方式”拆分,或者将多值转为多行。

学号姓名手机号座机号
001张三13800001234010-88888888
002李四13900005678(空)

总结:只要你的表里出现了“一组数据”塞在一个格子里的情况,就违反了第一范式。


第二范式:消除部分依赖

1.核心口号

“不能只靠一半。”

2.解决的问题

第二范式(2NF)建立在1NF的基础上。它主要针对复合主键(由两个或多个字段共同作为主键)的表。它要求:表中的非主键字段,必须完全依赖于整个主键,而不能只依赖主键的一部分。

3.反面教材(违反2NF)

假设我们有一张“学生选课成绩表”。

  • 一个学生可以选多门课。
  • 一门课也可以被多个学生选。
  • 所以,我们需要用【学号 + 课程名】这两个字段联合起来,才能唯一确定一条记录(比如张三的数学成绩)。
学号 (主键1)课程名 (主键2)成绩学生姓名所在系
001数学90张三计算机系
001英语85张三计算机系
002数学95李四外语系

问题分析:
我们来看看表里的非主键字段(成绩、学生姓名、所在系)对主键的依赖关系:

  • 成绩:必须知道“谁”(学号)考了“哪门课”(课程名),才能确定成绩。这是完全依赖,没问题。
  • 学生姓名:只要知道“学号”是001,就知道是“张三”。根本不需要知道“课程名”。这就是部分依赖(只依赖了主键的一半)。
  • 所在系:同理,只要知道学号,就知道他在哪个系,跟选了什么课无关。这也是部分依赖

如果不拆表,后果很严重:

  • 数据冗余:张三选了10门课,“张三”和“计算机系”这两个信息就要重复存储10次。
  • 更新异常:如果张三转系了,或者改名了,你需要把这张表里所有属于张三的记录全部找出来修改。漏改一条,数据就不一致了。
  • 插入异常:如果有一个新生(比如王五)刚入学,还没有选课(没有课程名),你就没法把他的名字存进这张表,因为主键的一部分(课程名)不能为空。

修正方案(符合2NF):
把只依赖“学号”的字段拆出去,建立新表。

表1:选课表(主键:学号+课程名)

学号课程名成绩
001数学90
001英语85

表2:学生表(主键:学号)

学号学生姓名所在系
001张三计算机系
002李四外语系

总结:只要表里有复合主键,就要检查有没有字段是“偷懒”的,只依赖了主键的一部分。如果有,就把它拆出去。


第三范式:消除传递依赖

1.核心口号

“不能隔山打牛。”

2.解决的问题

第三范式(3NF)建立在2NF的基础上。它要求:表中的非主键字段,必须直接依赖于主键,而不能依赖于另一个非主键字段。即:A决定B,B决定C,那么A决定C就是传递依赖,C应该被拆分出去。

3.反面教材(违反3NF)

现在我们看上面的“表2:学生表”。假设它的主键是学号

学号 (主键)学生姓名所在系系主任
001张三计算机系王教授
002李四计算机系王教授
003王五外语系赵教授

问题分析:
我们来分析依赖关系:

  • 学号 → 所在系:学号决定了学生属于哪个系。
  • 所在系 → 系主任:一个系通常只有一个系主任,所以“所在系”决定了“系主任”。
  • 结论:“系主任”是通过“所在系”间接依赖于“学号”的。这就是传递依赖

如果不拆表,后果很严重:

  • 数据冗余:计算机系有1000个学生,“王教授”这个名字就要重复存1000次
  • 更新异常:如果王教授退休了,换成了李教授。你需要修改学生表里所有“计算机系”对应的1000条记录。
  • 插入异常:如果学校刚成立了一个“人工智能系”,还没有招学生(没有学号),你就没法把这个新系和它的系主任存进数据库(因为主键学号不能为空)。

修正方案(符合3NF):
把“系主任”这个字段拆出去,让“所在系”做主键。

表1:学生表(主键:学号)

学号学生姓名所在系 (外键)
001张三计算机系
002李四计算机系

表2:系部表(主键:所在系)

所在系系主任
计算机系王教授
外语系赵教授

总结:只要发现表里有字段A依赖字段B,而字段B又依赖主键,那就赶紧把A拆出去。不要让非主键字段之间存在依赖关系。


总结与对比

为了方便记忆,我们可以把这三个范式看作是一个层层递进的“拆表”过程:

范式核心解决的问题依赖类型案例场景
1NF字段不可分一个格子里存了“手机,座机”。
2NF消除部分依赖非主键列只依赖主键的一部分选课表(学号+课程):姓名只依赖学号。
3NF消除传递依赖非主键列依赖另一个非主键列学生表(学号):系主任依赖所在系。

面试必背口诀

  • 1NF:原子性,列不可分。
  • 2NF:完全依赖,不依赖主键的一半(针对复合主键)。
  • 3NF:直接依赖,不隔山打牛(消除传递依赖)。

在实际开发中,一般数据库设计达到第三范式就足够了。当然,为了性能优化(比如减少表连接JOIN),有时候我们会适当进行“反范式化”设计,但这属于进阶话题,前提是你得先懂范式。

以上就是本篇文章的全部内容,喜欢的话可以留个免费的关注呦~~~

http://www.jsqmd.com/news/578810/

相关文章:

  • 基于Matlab的时滞系统GPC算法仿真:不同控制参数对控制效果的影响对比及程序调试说明
  • 【测试】认识测试
  • 海南全铝定制好口碑公司
  • 服务器异常流量如何识别?从监控定位到防御处置全流程
  • OpenClaw 的 “安全卫士”:Jeddak AgentArmor 运行时防护全解析
  • 三步打造你的专属AI对话伙伴:SillyTavern完整指南
  • Hooks(钩子)介绍
  • OpenClaw异常监控:Kimi-VL-A3B-Thinking长任务中断自恢复方案
  • 一、基础知识学习(Transformer + 上下文窗口 + Token 计算 + Embedding 向量)
  • 镜像视界|数字孪生公安新范式:视频不再监控,而是主动控制——基于视频空间反演与跨镜连续追踪的无感定位与轨迹预测系统
  • 全网可达作业
  • leetcode 1572. 矩阵对角线元素的和-耗时100-Matrix Diagonal Sum
  • 面向对象分析模型深入分析
  • 实现一个宿主机两个不通网桥的上的容器的互通 容器A内部访问容器B的容器名以及端口 容器A内部用宿主机ip+B容器端口映射的端口访问容器B 反之亦然
  • 何为多态?
  • 一篇文章让你彻底区分#define和typedef
  • 收藏!2026年小白/程序员转大模型:避坑+实战路线全拆解(亲测可落地)
  • wUU代码混淆实战指南:使用Obfuscar构建坚不可摧的安全防线
  • 嵌入式开发必备VScode插件全攻略
  • 2026 低代码平台的 7 个关键词:AI、信创、工作流、混合开发……
  • 还在手动逐字扒视频文本浪费时间?2026年这3款免费工具,5分钟搞定你2小时的工作量
  • java单例模式 懒汉式(双重检查锁)
  • 必收藏!小白程序员入门LLM:从应用到原理,掌控AI不被反制
  • Taskrunner:Arduino裸机实时任务调度器深度解析
  • 镜像视界 · 公安实战场景空间智能底座与目标连续控制体系白皮书——以 Pixel2Geo™ 像素空间反演引擎为核心,融合 MatrixFusion™ 矩阵视频融合与 NeuroRebuild™ 动态
  • 遇到GPU驱动冲突问题,云厂商通常提供怎样的技术支持?
  • STM32智能展柜控制系统设计与实现
  • 推挽电路原理与应用全解析
  • 为什么选择专业人力资源公司进行薪酬核算?5大优势助力企业高效合规
  • PDE (Processing D Editor) 三维场景编辑器 · 软件白皮书 · 基于 v..