欢迎光临
我们一直在努力

数据库五大范式(1NF/2NF/3NF/BCNF/4NF)零混淆案例

核心前置概念

1. 候选码(主键):能唯一标识整条记录的字段/字段组合

2. 主属性:出现在任意候选码中的字段

3. 非主属性:不在候选码里的普通业务字段

4. 函数依赖 X→Y:知道X就能唯一确定Y

5. 存在字段不能被完整主键唯一确定:不属于范式问题,表主键不合法,不满足关系数据库

一、1NF 第一范式(原子性)

1. 官方标准定义

数据表中所有字段都是原子的、不可再拆分,不允许多值、嵌套、组合字段。

2. 违规示例

学生表:(学号, 姓名, 联系方式)

数据:(1001, 张三, "138xxx;139xxx")

联系方式存储多个手机号,可拆分,违反1NF。

3. 合规改造

拆分为单行单值,一列只存一个数据。

一句话记忆

1NF:单元格不能分家

二、2NF 第二范式(消除:非主属性 部分依赖 候选码)

1. 官方精准定义

在满足1NF基础上:消除所有非主属性对候选码的部分函数依赖。

2. 人话解释

如果是复合主键,所有普通字段(非主属性),必须依赖完整主键,不能只靠主键其中一部分就能推导出来。

单字段主键天然满足2NF,只有复合主键才会违反2NF。

3. 纯净违规案例(只违反2NF,不牵扯3NF/BCNF)

订单明细表

复合候选码:订单ID + 商品ID

字段:订单ID、商品ID、订单时间、商品名称、购买数量

主属性:订单ID、商品ID

非主属性:订单时间、商品名称、购买数量

函数依赖分析

1. 订单ID → 订单时间(只依赖主键一部分)

2. 商品ID → 商品名称(只依赖主键一部分)

3. (订单ID+商品ID) → 购买数量(完全依赖)

违规核心

非主属性被部分主属性推导 = 违反2NF

这就是所有“部分依赖”的标准本质:普通字段,不需要整张主键,只靠主键片段就能确定。

4. 2NF 合规拆分

订单表(订单ID,订单时间)

商品表(商品ID,商品名称)

订单详情表(订单ID,商品ID,购买数量)

一句话记忆

2NF:非主属性,不许偷懒只靠一半主键

三、3NF 第三范式(消除:非主属性 传递依赖 候选码)

1. 官方精准定义

在满足2NF基础上:消除所有非主属性对候选码的传递函数依赖。

2. 人话解释

所有普通字段(非主属性),只能直接依赖主键,不能通过另一个普通字段间接依赖主键。

约束范围:只管非主属性,不管主属性。

3. 纯净违规案例(✅2NF ❌3NF,无任何2NF/BCNF问题)

支付渠道表

主键:渠道ID(单主键,天然满足2NF)

字段:渠道ID、渠道名称、结算ID、结算名称

函数依赖

渠道ID → 结算ID

结算ID → 结算名称

传递链:渠道ID → 结算ID → 结算名称

违规核心

结算名称是非主属性,不直接依赖主键,依赖另一个非主属性,传递依赖,违反3NF。

4. 3NF 合规拆分

渠道表(渠道ID,渠道名称,结算ID)

结算字典表(结算ID,结算名称)

一句话记忆

3NF:非主属性之间,不许互相依赖

四、BCNF 巴斯-科德范式

1. 官方精准定义

在满足3NF基础上:任何非平凡函数依赖 X→Y,X 必须是超码(候选码)。

2. 人话终极翻译

谁能决定别人,谁就必须是主键。

3. 2NF/3NF/BCNF 本质层级区别(你最需要的总结)

  • 2NF 只查:非主属性(有没有部分依赖)
  • 3NF 只查:非主属性(有没有传递依赖)
  • BCNF 全查:主属性 + 非主属性(堵死所有依赖漏洞)

重点:3NF 放行了「主属性之间的非法依赖」,BCNF 专门干掉它

4. 教科书零漏洞案例(✅2NF ✅3NF ❌BCNF)

关系:STJ(学生S, 教师T, 课程J)

业务规则:

1. 一个老师只教一门课:T→J

2. 学生选某个老师,就确定课程;学生选某课程,就确定老师

3. 双候选码:(S,T)、(S,J)

属性判定

所有字段 S、T、J 全部是主属性,无任何非主属性

逐层范式校验(绝对零错误)

✅ 满足2NF:没有非主属性,不存在部分依赖

✅ 满足3NF:没有非主属性,不存在传递依赖

❌ 违反BCNF:存在依赖 T→J

解析:T 是主属性,但 T 不是候选码,却能决定其他字段。违背「能决定别人的必须是主键」。

5. BCNF 合规拆分

TJ(教师T, 课程J) 主键:T

ST(学生S, 教师T) 主键:S+T

一句话记忆

BCNF:所有决定者,必须是主键

五、4NF 第四范式(消除独立多值依赖)

1. 官方精准定义

在满足BCNF基础上:消除所有不包含候选码的非平凡多值依赖。

2. 人话终极翻译

一张表内,多组互相无关的「一对多关系」,必须拆分独立表。

前面 2NF/3NF/BCNF 解决的都是函数依赖(一对一、多对一)问题;4NF 专门解决多值依赖(一对多)的数据冗余问题。

3. 核心前置:多值依赖通俗理解

多值依赖:已知X,能对应一组多个Y,且Y的取值和表中其他字段无关,记作

  • 平凡多值依赖:无需处理(字段互相包含)
  • 非平凡多值依赖:需要4NF强制拆分,杜绝冗余

4. 纯净违规案例(✅2NF ✅3NF ✅BCNF ❌4NF)

商户权限配置表(完全满足前三范式+BCNF,仅违反4NF)

表结构:商户ID、支付渠道、支付场景

业务规则:

1. 一个商户可开通多个支付渠道(微信、支付宝、云闪付)

2. 一个商户可适配多个支付场景(扫码支付、小程序支付、H5支付)

3. 支付渠道 和 支付场景 完全互相独立、无任何关联

4. 主键:商户ID(单主键,无任何部分依赖、传递依赖、非法主属性依赖)

违规数据演示

同一商户,两组独立一对多关系,强行混表产生笛卡尔积冗余:

MER001  微信  扫码支付

MER001  微信  小程序支付

MER001  支付宝  扫码支付

MER001  支付宝  小程序支付

多值依赖分析

1. 商户ID ->> 支付渠道

2. 商户ID ->> 支付场景

违规核心:同一主键下,存在两组互相独立的非平凡多值依赖,且不包含候选码,严重违反4NF。

5. 存在的业务问题

  • 海量数据冗余:渠道、场景自由组合,数据量成倍爆炸
  • 维护异常:新增一个支付场景,需要批量新增所有渠道关联数据
  • 脏数据风险:极易出现无效组合,数据一致性极差

6. 4NF 合规拆分改造

表1:商户支付渠道表(单组多值依赖,符合4NF)

(商户ID,支付渠道)

表2:商户支付场景表(单组多值依赖,符合4NF)

(商户ID,支付场景)

改造后:每张表只保留一组多值依赖,彻底消除独立多值依赖冗余,完全满足4NF。

一句话记忆

4NF:无关的一对多,坚决不共存一表

六、终极范式层级对照表

范式

解决问题

约束对象

核心口诀

1NF

字段可拆分、多值嵌套不原子

所有字段

原子不可拆

2NF

非主属性存在部分函数依赖

非主属性

不吃半主键

3NF

非主属性存在传递函数依赖

非主属性

不搞间接依赖

BCNF

主属性存在非法决定依赖(3NF盲区)

全部属性(主+非主)

能决定必是主键

4NF

存在独立非平凡多值依赖、笛卡尔积冗余

多值属性

无关一对多不同表

七、避坑总结

1. 只要表里有非主属性被主键片段推出 → 一定违反2NF,没资格谈BCNF

2. 3NF只管普通字段传递问题,完全不管主属性

3. BCNF是真正的“完美3NF”,堵死所有隐性依赖漏洞

4. 4NF 专门解决高维多值业务冗余问题(权限、标签、配置类表必备)

5. 开发实战:常规业务表做到3NF/BCNF即可,多标签、多配置、多维度一对多场景必须上4NF,杜绝数据爆炸

赞(0)
未经允许不得转载:171主机测评 » 数据库五大范式(1NF/2NF/3NF/BCNF/4NF)零混淆案例
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址