数据库三大范式: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 消传递依赖,最终实现数据 “简洁、一致、易维护”。
