候选键 = 所有能“唯一定一行”的最小字段集,不管它是 1 列还是 n 列。
表:学生(学号, 身份证号, 姓名, 年龄)
{学号} 就能唯一 → 它是一个候选键,而且是单属性的,不是组合键。
{身份证号} 也能唯一 → 另一个候选键,也是单属性。
{(学号, 身份证号)} 虽然也能唯一,但不是最小(去掉任一仍唯一),所以不是候选键,只是“超键”。
结论
这张表有两个候选键,但零个组合键;因此检查 2NF 时“部分依赖”压根儿不会出现。
如果给我左边的值,我就能唯一确定右边的值。继续上面的学生表:
学号 → 姓名
意思是:只要你知道学号,就一定能说出唯一一个姓名,不会出现“学号 1001 既叫张三又叫李四”。 学号 → 年龄 身份证号 → 姓名 身份证号 → 年龄这些都叫函数依赖。
学号 姓名 年龄 1001 张三 20 1002 李四 21
你知道学号 = 1001,就只能查到张三和20,不会出现第二行叫“张小三”或 19 岁。
于是说:
学号 → 姓名
学号 → 年龄
这就是两条函数依赖
1NF:
只要格子里的内容还能用逗号、空格、分号、连字符等再拆出更小含义,就违反 1NF;一格只放一项,就满足 1NF。
不及格的电话列(违反 1NF) 姓名 电话 张三 1380000,1390000 电话列里用逗号把两个号码拼在一起 → 它还能再拆成两条有用信息(1380000 和 1390000)。 于是这列不是原子值 → 不满足 1NF。 合格的电话列(满足 1NF) 把多值拆成多行,每格只放一个号码: 姓名 电话 张三 1380000 张三 1390000 现在“电话”列里没有逗号、空格、分号等再分符号,一格就是一个不可分割的号码 → 原子值 → 满足 1NF。 其他常见“非原子”陷阱 地址列写“北京市 海淀区 学院路”,如果业务里经常要单独查“区”,这列就可再拆 → 非原子。 课程列写“语文,数学,英语” → 非原子。 成绩列写“90-100” → 非原子。
2NF:
组合主键时,非主属性不能只依赖主键的一部分
学号 | 姓名 | 课程号 | 课程名 | 成绩 | 学分 |
---|
例子 1:1NF 关卡——“列里还能再拆吗?”
题目:上表是否满足 1NF?
检查:每一列都是不可再分的原子值(没有逗号、空格列表)。
结论:满足 1NF ✅
如果不满足:会出现“电话”列里存“138,139”这种多值,拆成多行即可。
“拆表”升到 2NF:
R(教师, 课程, 教室)