系统架构师-数据库技术(三大范式)

2026年01月20日/ 浏览 8

数据库三大范式:3 分钟读懂数据规范化逻辑

大家好,今天讲数据库的 三大范式(1NF、2NF、3NF)。它们的核心目标是消除数据冗余、避免更新异常,就像整理房间:先拆零散物品(1NF),再归整同类(2NF),最后去重精简(3NF)。结合实例一步步拆解。

一、第一范式(1NF):数据 “不可再拆” 的基础

1NF 是所有范式的前提,核心要求:关系中的每一个分量必须是不可分的数据项(不能有 “复合字段”)。

反例:若 “学生表” 里有 “联系方式” 列,包含 “电话 + 邮箱”(如 “138xxx;xxx@mail.com”),就不符合 1NF——“联系方式” 可再拆。正例:将 “联系方式” 拆为 “电话”“邮箱” 单独列,每个列的值都是 “最小单元”,才满足 1NF。

你给的 “学生 (学号,学生姓名,系号,系主任姓名,课程号,成绩)” 表,所有列都是不可分的,满足 1NF,但问题才刚刚开始。

二、第二范式(2NF):消除 “部分依赖”,拆分表结构

2NF 的要求:满足 1NF,且非主属性完全依赖于候选码(不能依赖复合候选码的某一部分)。

1. 先明确关键概念

候选码:上节课讲的 “最小超键”,这里表的候选码是 **(学号,课程号)**(只有这两个组合能唯一确定 “成绩”)。非主属性:除候选码外的列(姓名、系名、系主任、成绩)。部分依赖:非主属性只依赖候选码的一部分(比如 “姓名” 只依赖 “学号”,不依赖 “课程号”)。

2. 原表的问题

原 “学生表” 不满足 2NF:非主属性 “姓名”“系名” 等只依赖 “学号”(候选码的一部分),导致数据冗余(同一学生选多门课,姓名、系名重复存储)。

3. 解决:按 “完全依赖” 拆分表

拆分为两张表,让非主属性都完全依赖各自表的候选码:

学生 (学号,学生姓名,系名,系主任):候选码是 “学号”,所有非主属性都依赖 “学号”(完全依赖);选课 (学号,课程号,成绩):候选码是 “(学号,课程号)”,“成绩” 依赖这个组合(完全依赖)。拆分后,两张表均满足 2NF。

三、第三范式(3NF):消除 “传递依赖”,去重精简

3NF 的要求:满足 2NF,且不存在非主属性对码的传递依赖(不能有 “A→B→C” 的间接依赖)。

1. 拆分后表的新问题

“学生 (学号,学生姓名,系名,系主任)” 表满足 2NF,但存在传递依赖:学号→系名→系主任—“系主任” 不直接依赖主键 “学号”,而是通过 “系名” 间接依赖,导致冗余(同一系的学生,系主任重复存储)。

2. 解决:按 “直接依赖” 再拆分

拆去传递链条,让非主属性都 “直接依赖” 主键:

学生 (学号,学生姓名,系名):“系名” 直接依赖 “学号”;系 (系名,系主任):“系主任” 直接依赖 “系名”(“系名” 是这张表的候选码);选课 (学号,课程号,成绩):无传递依赖,保留不变。

现在三张表均满足 3NF,数据无冗余,更新系主任时只需改 “系表”,不会漏改。

一句话总结

三大范式是 “递进式规范”:1NF 拆不可分,2NF 消部分依赖,3NF 消传递依赖,最终实现数据 “简洁、一致、易维护”。

picture loss