🗄️ 第五章 引入数据库-数据库的结构与表的设计
📄 一句话概括

第二范式(2NF):满足 1NF 之后,非主键列必须认整个主键——复合主键里只认一半的列,请搬去它真正归属的表。这消灭的是「部分依赖」。

📝 本节和前面几节的关系

三台阶第二阶。它只在复合主键场景出现(单列主键的表天生满足 2NF)。核心动作:把「只认半个主键」的列拆回自己家——拆完的形状正是 5-6 的中间表。

一、问题表:半个主键养活一列

成绩(学号+课程号 PK, 成绩, 课程名, 学分)

二、部分依赖的三宗罪

三、整改:各回各家

成绩(学号 FK, 课程号 FK, 成绩)       ← 中间表:整键依赖,干干净净
课程(课程号 PK, 课程名, 学分)        ← 被拆出来的「其他种类」

2NF 的动作=把「只认半个主键」的列,搬进以那半个主键为主键的表——正是 5-6 多对多中间表的标准形状。

四、动手 Demo:冗余当场现形

-- 违规表:课程信息跟着每条成绩重复
CREATE TABLE bad_score (
    student_id INT,
    course_id  INT,
    score      DECIMAL(5,2),
    course_name VARCHAR(20),       -- 部分依赖!
    PRIMARY KEY (student_id, course_id)
);
INSERT INTO bad_score VALUES (1,10,85,'数学'),(2,10,90,'数学'),(3,10,78,'数学');
-- 「数学」抄了 3 遍;课程改名要改 3 行

-- 2NF 整改后
CREATE TABLE courses (course_id INT PRIMARY KEY, course_name VARCHAR(20));
CREATE TABLE scores (
    student_id INT, course_id INT, score DECIMAL(5,2),
    PRIMARY KEY (student_id, course_id)
);

课程改名:违规表改 3 行(500 行呢?),规范表改 1 行。

五、30 秒实验

单列主键的表会有部分依赖吗?(不会——主键只有一列,要么依赖它要么不依赖;「不依赖」的列留给 3NF 处理。)所以 2NF 只在复合主键表上有戏份。

六、常见误区

自测三问 1. 2NF 消灭什么?(部分依赖——非主键列只认复合主键的一半) 2. 为什么单列主键表天然满足 2NF?(主键只有一列,不存在认一半) 3. 部分依赖的三宗罪?(冗余/更新异常/插不进新课)

相关笔记