news 2026/8/8 12:02:10

数据库三范式(1NF、2NF、3NF)与反范式化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数据库三范式(1NF、2NF、3NF)与反范式化

前言

数据库范式听起来好像很难,其实它就是用来约束表设计的几层“规矩”。遵守这些规矩,主要是为了减少数据冗余避免数据异常

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

✅ 核心要求:原子性

表中每一列都必须是不可拆分的最小数据单元,不能一个格子里塞多个数据。

❌ 错误例子

学号姓名出生年月日
001张三2000-01-01

如果出生年月日在业务中需要拆成年、月、日单独使用,那这一列就不是“最小单元”,违反了 1NF。

✅ 正确做法(二选一)

  1. 拆成三个列:出生年出生月出生日
  2. 出生年月日当成一个整体,业务上永远不拆分,也符合 1NF。

一句话:列里不能再套列,一个格子只存一个拆不开的值。

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

前提:已满足 1NF

✅ 核心要求:所有非主键列必须完全依赖于“整个主键”

如果一个表的主键是由多列组成的联合主键,那么每个非主键列都必须依赖于这个联合主键的全部,不能只依赖其中的一部分。

❌ 错误例子:选课表

主键:(学号, 课程号)

学号课程号姓名学分
001C01张三2
001C02张三3
002C01李四2

问题:部分依赖

  • 姓名只依赖于学号(不管选啥课,姓名不变)
  • 学分只依赖于课程号(不管谁选 C01,学分都是 2)

🚨 会引发的异常

  1. 数据冗余:张三选 3 门课,“张三”被存 3 次
  2. 删除异常:删光所有选课记录,课程的学分信息也跟着丢了
  3. 插入异常:新课没人选,就无法单独录入课程
  4. 更新异常:C01 学分要从 2 改 3,所有选 C01 的记录都得改,漏一条就数据不一致

✅ 正确做法:拆成 3 张表

学生表(主键:学号)

学号姓名
001张三
002李四

课程表(主键:课程号)

课程号学分
C012
C023

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

学号课程号成绩
001C0180
001C0290

现在每一列都只依赖于自己表的完整主键

一句话:联合主键时,非主键列不能只认主键中的一部分。

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

前提:已满足 2NF

✅ 核心要求:非主键列不能“隔代依赖”,必须直接依赖主键

不能出现“主键 → 非主键 A → 非主键 B”这种间接的依赖链。

❌ 错误例子:学生表

主键:学号

学号姓名学院名称学院电话
001张三计算机学院123456
002李四计算机学院123456
003王五文学院654321

问题:传递依赖
学号 → 学生→ 学院名称 → 学院电话
学院电话实际上是通过学院名称才间接依赖学号的,这就叫“隔代依赖”。

🚨 会引发的异常

  1. 数据冗余:计算机学院的电话被重复存储
  2. 更新异常:学院电话从 123456 改成 654321 时,所有该学院学生的记录都得改,漏一条就会出数据不一致的 Bug

✅ 正确做法:拆成 2 张表

学生表(主键:学号)

学号姓名学院ID
001张三01
002李四01

学院表(主键:学院ID)

学院ID学院名称学院电话
01计算机学院123456
02文学院654321

现在电话直接依赖于学院ID,学生表只存学院ID,依赖链被切断。

一句话:非主键列之间不能互相依赖,只能和主键直接绑定。

四、反范式化:适当打破规则

实际开发中,一般到 3NF 就足够了。但有时为了性能,会故意保留一些冗余,这叫反范式化——用空间换时间。

典型例子:订单金额

订单ID单价数量金额
100110330

严格来说,金额可以由单价 × 数量算出来,属于冗余字段,违反了 3NF。
但我们常常会保留它,因为查询统计时直接读金额比临时计算要快得多,这就是以空间换时间的做法。

五、范式化 vs 反范式化 优缺点对比

对比维度范式化设计(满足 3NF)反范式化设计(保留冗余)
数据冗余几乎没有,数据表体积小存在冗余,占用更多存储空间
更新操作改一处即可,无数据不一致风险需同步更新所有冗余副本,维护成本高
查询性能复杂查询需多表关联,数据量大时较慢大部分查询可用单表或少量关联完成,速度快
索引优化多表关联场景下索引优化难度高表结构集中,更容易针对性地建立索引
数据一致性天然保障必须通过额外逻辑(触发器/业务代码)保障

六、总结

  • 1NF:列不可再分,追求原子性
  • 2NF:消除部分依赖,联合主键时,非主键列必须依赖整个主键
  • 3NF:消除传递依赖,非主键列只能直接依赖主键
  • 反范式化:故意违反范式,用冗余换性能

数据库设计没有绝对的银弹,范式化保证数据整洁,反范式化提升查询效率,实际项目中要根据业务场景在两者之间找到平衡。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/8 11:57:15

告别枯燥代码:如何在浏览器中优雅阅读Markdown文件的5个步骤

告别枯燥代码:如何在浏览器中优雅阅读Markdown文件的5个步骤 【免费下载链接】markdown-viewer Markdown Viewer / Browser Extension 项目地址: https://gitcode.com/gh_mirrors/ma/markdown-viewer 还在为浏览器中打开Markdown文件只能看到原始代码而烦恼吗…

作者头像 李华
网站建设 2026/8/8 11:56:33

【信息科学与工程学】【财务领域】第一百三十三篇 ICT产品的进项与出项02

编号 类型 进项 进项的内容及采购来源及采购品类及材料类型 进项的业务财务模型的数学表达式及数值/数字 进项对应的出项及来源品类及材料类型 出项对应的业务财务模型的数学表达式及数字/数值 关联知识 501 路由器 线卡 (Line Card)​ 内容:插入路由器机箱的业务板…

作者头像 李华
网站建设 2026/8/8 11:55:19

警惕AI编程巨婴化:MirrorForge工具深度解析与实践

1. 为什么我们需要警惕Agent Coding的"巨婴化"陷阱 最近半年,AI编程助手的使用率增长了近300%,但一个有趣的现象是:很多开发者开始过度依赖这些工具,甚至出现了不会写基础循环语句却能"开发"完整项目的极端案…

作者头像 李华
网站建设 2026/8/8 11:53:37

基于自动化控制架构的企业微信群消息管理系统设计

摘要 在多群组协同办公与数字化客户运营场景中,随着业务量的激增,企业往往面临多群组信息流转不及时、人工跨群同步效率低等痛点。由于特定业务场景下的复杂交互需求,单纯依赖传统接口有时难以覆盖所有桌面端交互行为。本文将分享一种基于 W…

作者头像 李华
网站建设 2026/8/8 11:51:57

Cangaroo架构解析:实现毫秒级延迟的CAN总线实时数据处理系统

Cangaroo架构解析:实现毫秒级延迟的CAN总线实时数据处理系统 【免费下载链接】cangaroo Open source can bus analyzer software - with support for CANable / CANable2, CANFD, and other new features 项目地址: https://gitcode.com/gh_mirrors/ca/cangaroo …

作者头像 李华