了解基本术语
一、核心「键」术语对照表
| 术语 | 通俗定义 | 大白话速记 | 关键规则 |
|---|---|---|---|
| 超键 | 能唯一确定一行数据的字段/字段组合,可带多余字段 | 能找人就行,带不带累赘不管 | 只要求唯一性,不要求精简 |
| 候选键 | 最精简的超键,去掉任意一个字段就无法唯一确定数据 | 精干小分队,刚好能找人 | 是主键的候选人,一张表可以有多个 |
| 主键 | 从候选键里人为选定的、官方唯一标识 | 表的官方身份证号 | 一张表只能有一个,不能为空、不能重复 |
| 外键 | A表中的字段,刚好是B表的主键 | 两张表的联姻凭证 | 用来关联表,保证数据对应关系合法 |
| 主属性 | 所有候选键里出现过的字段 | 有资格当主键的「领导层」 | 不是只有主键字段才算,所有候选键包含的字段都是 |
| 非主属性 | 从未出现在任何候选键里的字段 | 纯纯的「小弟」 | 只能被别人决定,不能决定别人 |
二、核心「依赖」术语对照表
| 术语 | 通俗定义 | 大白话速记 | 对应消除范式 |
|---|---|---|---|
| 函数依赖 | 确定A就能唯一确定B,记作A→B | A能说了算B | 范式的基础概念 |
| 部分函数依赖 | 组合主键里,非主属性只依赖主键的一部分 | 小弟只认半个大哥团队 | 2NF消除 |
| 传递函数依赖 | A→B,B→C,C通过B间接依赖A | 小弟通过中间商认大哥 | 3NF消除 |
| 多值依赖 | 一张表里同时存在两个独立的一对多关系 | 两个不相干的事挤一张表 | 4NF消除 |
先铺垫:范式到底是啥?
数据库范式,就是设计数据库表的“整洁等级” ,从1NF到4NF,等级越高,表拆得越细,数据重复越少,也越不容易出现“加不进去、删错了、改半天”的奇葩问题。
就像整理书包:
- 1NF = 把东西都摊开,不揉成一团
- 2NF = 分课本、文具两个袋子装
- 3NF = 课本里再分语文袋、数学袋
- BCNF = 袋子上的标签也不能互相混淆
- 4NF = 水杯、跳绳这种和课本无关的也单独放
核心原则只有一句话:一张表只说一件事。
1NF(第一范式):每个格子只能放一个东西
核心要求:表中每一列都是不可拆分的“最小单元”,不能一列塞好几个信息。 大白话:每个格子只能放一个东西,不能打包塞一堆。
❌ 不符合1NF的反面教材:
| 学号 | 个人信息 |
|---|---|
| 001 | 张三,男,一班 |
“个人信息”列同时装了姓名、性别、班级,还能继续拆,所以不符合1NF。
✅ 符合1NF的正确打开方式:
| 学号 | 姓名 | 性别 | 班级 |
|---|---|---|---|
| 001 | 张三 | 男 | 一班 |
1NF是最基础的门槛,连这个都达不到,后面的都免谈。
2NF(第二范式):小弟必须认整个大哥团队,不能只认一个
先补个常识:主键就是能唯一确定一行数据的“身份证”,可以是一个字段,也可以是几个字段组队。
核心要求:在1NF基础上,所有非主键字段,必须完全依赖整个主键,不能只依赖主键的一部分。 大白话:主键如果是“双人组合”,那每个小弟都必须认整个组合,不能只跟组合里一个人混。
❌ 不符合2NF的反面教材(成绩表,主键是「学号+课程号」组队):
| 学号 | 课程号 | 姓名 | 课程名 | 分数 |
|---|---|---|---|---|
| 001 | 101 | 张三 | 数学 | 90 |
| 002 | 101 | 李四 | 数学 | 85 |
问题出在哪?
主键是「学号+课程号」两个人组队,但:
- 「姓名」只靠「学号」就能确定,跟课程号没关系 → 只认了半个大哥
- 「课程名」只靠「课程号」就能确定,跟学号没关系 → 也只认了半个大哥
- 只有「分数」必须「学号+课程号」一起才能确定 → 认了整个团队
会惹什么麻烦?
- 冗余爆炸:数学这门课100个学生选,“数学”俩字要重复存100遍
- 插不进去:新开一门课,还没人选,这门课的信息根本插不进去(主键里学号不能为空)
- 删没了:某门课所有人都退课了,这门课本身的信息也跟着被删掉了
- 改累死:把“数学”改成“高等数学”,得改100条记录
✅ 怎么改符合2NF?拆表! 一张表拆成三张,每张只干一件事:
- 学生表(学号,姓名)→ 主键:学号
- 课程表(课程号,课程名)→ 主键:课程号
- 成绩表(学号,课程号,分数)→ 主键:学号+课程号
现在每张表里,非主键字段都完全依赖主键,符合2NF。
3NF(第三范式):小弟只能直接认大哥,不能认小弟的小弟
核心要求:在2NF基础上,消除传递依赖——非主键字段不能依赖其他非主键字段,必须直接依赖主键。 大白话:小弟只能直接认大哥,不能通过另一个小弟间接认大哥,中间不许有“中间商”。
❌ 不符合3NF的反面教材(学生表,主键是「学号」):
| 学号 | 姓名 | 班级 | 班主任 |
|---|---|---|---|
| 001 | 张三 | 一班 | 王老师 |
| 002 | 李四 | 一班 | 王老师 |
问题出在哪?
「班主任」不直接依赖学号,而是依赖「班级」,「班级」才依赖学号。 相当于:学号 → 班级 → 班主任,中间隔了一层,这就是“传递依赖”。
会惹什么麻烦?
和2NF的麻烦一模一样:
- 一班50个学生,“王老师”重复存50遍
- 新班级没学生,班主任信息插不进去
- 学生都毕业,班主任信息也没了
- 换班主任得改50条记录
✅ 怎么改符合3NF?继续拆!
- 学生表(学号,姓名,班级号)→ 主键:学号
- 班级表(班级号,班主任)→ 主键:班级号
现在所有非主键字段都直接依赖主键,没有中间商赚差价,符合3NF。
划重点:3NF是业界最常用的范式,绝大多数业务系统设计到3NF就够用了。
BCNF(巴斯范式):连大哥内部也不能互相管
这是最容易懵的,也是你重点想听的,咱们掰开揉碎讲。
先回忆3NF的漏洞
3NF的规矩是:只管“小弟”(非主键字段),不管“大哥团队”(主键里的字段)内部。 3NF说“小弟不能依赖小弟”,但没说“大哥团队里,一个大哥不能管另一个大哥”。
BCNF就是把这个漏洞补上了。
核心要求:只要某个字段能决定别的字段,那它自己必须是完整的主键(候选键)。 大白话:不管是大哥还是小弟,只要你能说了算,你就必须是“一把手”,不能是二把手就能管另一个二把手。
举个生活化的例子:社团报名表
先定规则:
- 每个社团只有1个指导老师
- 每个老师只指导1个社团
- 一个学生可以报多个社团,一个社团有多个学生
❌ 符合3NF,但不符合BCNF的表(主键是「学生+社团」):
| 学生 | 社团 | 指导老师 |
|---|---|---|
| 张三 | 篮球社 | 李老师 |
| 李四 | 篮球社 | 李老师 |
| 张三 | 动漫社 | 王老师 |
先讲:为什么它符合3NF?
这张表里,能当主键的组合有两个:
- 「学生 + 社团」→ 能确定老师
- 「学生 + 老师」→ 能确定社团
也就是说,三个字段都是“有资格当主键的人”(主属性),没有纯小弟(非主属性) 。 而3NF管的是“非主属性不能依赖非主属性”,既然连非主属性都没有,那它天然符合3NF。
但它有大问题:
- 插不进去:我想新成立“围棋社”,指定“赵老师”当指导,但还没人报名。根本插不进去——因为主键里的“学生”不能为空。
- 改累死:篮球社换指导老师了,得把所有报篮球社的学生记录都改一遍。
- 删没了:篮球社的学生都退社了,篮球社和李老师的对应关系也跟着没了。
病根在哪?
「社团」能决定「指导老师」,但「社团」自己不是一个完整的主键(主键是学生+社团组队)。 它只是大哥团队里的一员,却能决定另一个大哥成员——这就是BCNF禁止的。
✅ 怎么改符合BCNF?拆成两张表:
- 社团表(社团,指导老师)→ 主键:社团
- 报名表(学生,社团)→ 主键:学生+社团
现在再看:
- 社团表里,社团是主键,老师依赖社团 → 能决定别人的,自己就是完整主键
- 报名内外,学生+社团是主键,没有其他字段 → 没问题
所有“能说了算”的字段,自己都是完整的一把手,完美解决所有异常。
一句话记住3NF和BCNF的区别
- 3NF:小弟不能依赖小弟(管住底层)
- BCNF:大哥内部也不能互相依赖(管住高层)
- 更简单的记法:一张表里,只要“A能推出B”,A就必须是整张表的主键。
4NF(第四范式):一张表不能有两个独立的“一对多”
核心要求:在BCNF基础上,消除多值依赖——一张表里不能同时有两个互相独立的“一对多”关系。 大白话:一张表只讲一个“一对多”,两个没关系的一对多不能放一起,不然会交叉繁殖出一堆冗余数据。
❌ 不符合4NF的反面教材:
| 学生 | 兴趣 | 特长 |
|---|---|---|
| 张三 | 篮球 | 画画 |
| 张三 | 篮球 | 钢琴 |
| 张三 | 游泳 | 画画 |
| 张三 | 游泳 | 钢琴 |
一个学生可以有多个兴趣,也可以有多个特长,兴趣和特长之间半毛钱关系都没有。 张三有2个兴趣、2个特长,结果存了4条记录(2×2)。如果有3个兴趣、4个特长,就要存12条,冗余爆炸。
✅ 怎么改符合4NF?拆!
- 学生兴趣表(学生,兴趣)→ 管兴趣这一个一对多
- 学生特长表(学生,特长)→ 管特长这一个一对多
各管各的,互不干扰,冗余立刻消失。
最后一张表总结
| 范式 | 核心目标 | 大白话记忆 |
|---|---|---|
| 1NF | 字段原子性 | 每个格子只放一个东西 |
| 2NF | 消除部分依赖 | 小弟必须认整个大哥团队 |
| 3NF | 消除传递依赖 | 小弟只能直接认大哥 |
| BCNF | 消除主属性内部依赖 | 能说了算的,必须是完整大哥 |
| 4NF | 消除多值依赖 | 一张表只能有一个“一对多” |
实际开发小建议
- 绝大多数业务场景,3NF就够用了,兼顾整洁和查询性能。
- 要求高一点可以到BCNF,进一步减少数据异常。
- 4NF用得很少,一般只有数据仓库、极端去冗余场景才会用到。
- 范式不是越高越好:表拆得越多,查询时连表就越多,性能会下降。有时候为了查询快,还会故意“反范式”(加一点冗余字段)。