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

数据库三范式

数据库三范式

数据库三范式 (Database Normalization) 就是一套“防坑指南”

如果不遵守范式,你的数据库就会变成一个巨大的垃圾场,充满冗余数据(浪费空间)和异常(想改一个数据要改 100 个地方,改漏了就出 Bug)。


第 0 阶段:混乱的原始表 (Unnormalized Form)

想象你在做一个教务系统,最开始为了省事,你把所有信息都塞进了一张 Excel 大表里:

全能表 (Universal Table)

学号 (Sno) 姓名 (Name) 系名 (Dept) 系主任 (Dean) 课号 (Cno) 学分 (Credit) 成绩 (Grade)
101 张三 计算机 老王 C1 4 90
101 张三 计算机 老王 C2 2 85
102 李四 数学 老李 C1 4 88

这张表有巨大的问题(异常):

  1. 冗余:张三选了 10 门课,“计算机”和“老王”就要重复存 10 次。
  2. 更新异常:如果系主任换人了,你得把表里所有“计算机系”的学生记录全改一遍。漏改一个,数据就不一致了。
  3. 插入异常:如果新开了一个“物理系”,但还没招到学生,这个系就存不进去(因为主键 Sno 不能为空)。

为了解决这些问题,我们需要范式 (Normalization)


第一范式 (1NF):原子性 (Atomicity)

核心规则:所有的格子都不能再拆分。

  • 反例:如果有一列叫“联系方式”,里面填了 电话:123, 微信:abc
  • 整改:必须拆成两列 电话微信。或者拆成两行。
  • 判断标准只要是关系型数据库(MySQL, Oracle),建表时天然就符合 1NF。如果不符合,你也建不出表来(除非你存 JSON,那是另一回事)。

第二范式 (2NF):消灭部分依赖 (No Partial Dependency)

这是初学者最容易晕的地方。

核心规则:非主键列必须依赖于“整个”主键,而不能只依赖主键的“一部分”。

(前提:表必须有复合主键,即主键由两个或多个列组成。如果主键只有一列,自动符合 2NF。)

回到我们的例子

  • 主键:(Sno, Cno) —— 你需要“学号”和“课号”两个才能唯一确定一条选课记录。
  • 分析依赖关系
    1. 成绩 (Grade) \(\to\) 依赖于 (Sno, Cno)。 (正确!也就是:是谁、在哪门课考的成绩)
    2. 姓名 (Name) \(\to\) 依赖于 (Sno, Cno) 吗?不! 名字只依赖于 Sno (学号)。哪怕你不选课,张三还是张三。
    3. 学分 (Credit) \(\to\) 依赖于 (Sno, Cno) 吗?不! 学分只依赖于 Cno (课号)。

这就是部分依赖(只依赖了主键的一部分)。这会导致数据冗余。

整改方案:把表拆开!

  1. 学生表\(Student(Sno, Name, Dept, Dean)\) —— 主键是 Sno
  2. 课程表\(Course(Cno, Credit)\) —— 主键是 Cno
  3. 选课表\(SC(Sno, Cno, Grade)\) —— 主键是 (Sno, Cno)

现在,Name 只依赖 SnoCredit 只依赖 CnoGrade 依赖 (Sno, Cno)

完美符合 2NF!


第三范式 (3NF):消灭传递依赖 (No Transitive Dependency)

核心规则:非主键列必须直接依赖于主键,不能“隔山打牛”。

看看刚才拆分出来的 学生表

\(Student(Sno, Name, Dept, Dean)\)

  • 主键Sno
  • 依赖关系
    1. Sno \(\to\) Dept (学号决定系别)
    2. Dept \(\to\) Dean (系别决定系主任)
    3. 所以:Sno \(\to\) Dept \(\to\) Dean

这就是传递依赖

问题:如果“计算机系”改名了,或者换主任了,你得去学生表里改。这不合理,系主任是谁,跟具体的学生没关系,是系的事情。

整改方案:继续拆!

  1. 学生表\(Student(Sno, Name, Dept)\)

    (注意:这里只留 Dept 作为外键)

  2. 系部表\(Department(Dept, Dean)\)


总结:三范式通关口诀

为了方便记忆,请记住这句数据库界的至理名言(改编自 Bill Kent):

所有属性必须依赖于主键(1NF),

依赖于整个主键(2NF),

且除了主键之外别无他物(3NF)。

(The Key, the Whole Key, and Nothing but the Key.)

范式 解决的问题 关键词 判断方法
1NF 数据原子性 不可分 每个格子里只能有一个值
2NF 数据冗余 部分依赖 只有复合主键时才需考虑。非主键列必须依赖全部主键
3NF 数据解耦 传递依赖 非主键列之间不能有依赖关系 (A决定B,B决定C)

工程视角的“反转”:反范式化 (Denormalization)

“虽然范式能减少冗余,保证一致性,但在实际高并发业务(如电商大促、报表分析)中,严格遵守 3NF 会导致表被拆得太散

每次查询都要 JOIN 很多张表(学生 JOIN 选课 JOIN 课程 JOIN 系部),性能极差。

所以,我们在设计数据仓库 (Data Warehouse)高性能读服务时,会故意违反 3NF,进行反范式化——把‘系名’甚至‘课程名’冗余回学生表里,用空间换时间。”

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

相关文章:

  • 2026春节档观影不踩雷:全类型影片汇总,适配带爸妈、约朋友、全家看全场景 - SFMEDIA
  • 2026国内最新玻璃胶生产商TOP5推荐:服务深度覆盖江苏、山东、济南、云南等地,高端定制/抗菌防霉/防水型等多场景适配,权威榜单助力精准选择 - 品牌推荐2026
  • 零基础学历提升必看!3家正规机构实测推荐,小白不踩雷 - 品牌测评鉴赏家
  • 2026口碑好的学历提升培训机构盘点!在职党/零基础直接抄作业,避坑不踩雷 - 品牌测评鉴赏家
  • 实用指南:华为云国际版 vs 阿里云国际版:东南亚市场选型指南
  • 2026春节档电影推荐指南:六部主力新片怎么选(全家人一起/带爸妈/朋友局) - SFMEDIA
  • 回收携程任我行礼品卡选对平台,京顺回收多赚的钱能再计划一次短途游 - 京顺回收
  • 上班族学历提升避坑|3家正规机构实测推荐,省时不花冤枉钱 - 品牌测评鉴赏家
  • Java高频面试题:Zookeeper的通知机制是什么?
  • 2026口碑封神!实测5家靠谱学历提升机构,上班族/零基础避坑抄作业 - 品牌测评鉴赏家
  • 数据编目在医疗大数据中的应用实践
  • 避坑指南|2026学历提升培训机构哪家好?博主实测整理,新手直接抄作业 - 品牌测评鉴赏家
  • 2026高性价比学历提升培训机构|实测避坑,上班族/零基础闭眼冲 - 品牌测评鉴赏家
  • 别再乱选!2026实测靠谱学历提升机构|上班族/零基础闭眼冲(无广纯干货) - 品牌测评鉴赏家
  • 2026执业药师冲刺押题班口碑红黑榜!3大宝藏机构+避坑指南,考生必看 - 品牌测评鉴赏家
  • 2026执业药师高性价比培训机构,备考党少花冤枉钱 - 品牌测评鉴赏家
  • day10 - 呓语
  • 二战执业药师备考逆袭指南:3家宝藏培训机构实测推荐,避开这些坑! - 品牌测评鉴赏家
  • 供应链服务率提升 95%→99%,为什么成本会爆炸及对策
  • YOLOv13涨点改进 | 全网独家创新、特征融合改进篇 | TGRS 2025顶刊| 引入MROD-YOLO的 MSIA多尺度迭代聚合模块,强化语义特征之间交互,提升复杂环境中小目标检测,多模态融合
  • 实测不踩雷|2026执业药师备考培训哪家好?在职/零基础直接抄作业 - 品牌测评鉴赏家
  • 大数据多维分析中的SQL技巧与最佳实践
  • 2026执业药师培训排名前十机构|实测不踩坑,考生必看! - 品牌测评鉴赏家
  • 执业药师备考封神!4大机构+6位名师课程推荐,零基础也能轻松冲 - 品牌测评鉴赏家
  • AI原生应用开发工具链:2024年最值得关注的10个工具
  • 执业药师考试培训优选指南:选对机构,通关更高效 - 品牌测评鉴赏家
  • 2026执业药师线上培训口碑|5家机构,避开坑点直接冲 - 品牌测评鉴赏家
  • 提示工程架构师的DevOps实战:用持续反馈优化提示
  • 2026年必知!口碑炸裂的执业药师考试培训机构大盘点 - 品牌测评鉴赏家
  • React 快速判断当前环境