🗄️ 第四章 管理数据-避免非法数据的功能
📄 一句话概括

UNIQUE 保证列里全表无重复:第二个相同的值一进门就报错——邮箱、身份证号、用户名这类「天下无双」的列都靠它把关。它和主键是近亲但不同:UNIQUE 允许 NULL、一张表可以有多个。

📝 本节和前面几节的关系

拦完空值(4-9),本节拦重复。本节还埋着与 4-12 主键的对比线:主键 = NOT NULL + UNIQUE 的加强版——表里只此一个、且不许空;UNIQUE 则灵活得多。

一、语法与效果

CREATE TABLE users (
    id     INT PRIMARY KEY,
    name   VARCHAR(20),
    email  VARCHAR(50) UNIQUE      -- 邮箱全表唯一
);

INSERT INTO users VALUES (1, '张三', '[email protected]');   -- 成功
INSERT INTO users VALUES (2, '李四', '[email protected]');   -- 报错:UNIQUE constraint failed

同样的邮箱第二次插入当场被拒——不需要查重程序,数据库自己会查。

二、UNIQUE vs PRIMARY KEY(本节重点)

对比 UNIQUE PRIMARY KEY
全表唯一 ✅ ✅
允许 NULL ✅(可以有 NULL) ❌
一张表几个 可以有多个(email、手机号各来一个) 只能一个

口诀:主键是「身份证」,UNIQUE 是「其他证件」——身份证必须且仅有一张,其他证件可以办好几本,甚至可以不办(NULL)。

三、组合 UNIQUE:两列合起来才唯一

CREATE TABLE scores (
    student_id  INT,
    subject     VARCHAR(20),
    score       DECIMAL(5,2),
    UNIQUE (student_id, subject)    -- 同一学生同一科目只能一条
);

单个列看可以重复(张三有数学也有英语,student_id 重复;数学科目人人有,subject 重复),但「张三 + 数学」这个组合全表只能出现一次——选课表、成绩表都这么建。

四、动手 Demo:单列与组合

-- 单列 UNIQUE
CREATE TABLE t1 (email VARCHAR(50) UNIQUE);
INSERT INTO t1 VALUES ('[email protected]');
INSERT INTO t1 VALUES ('[email protected]');      -- 报错
INSERT INTO t1 VALUES (NULL);
INSERT INTO t1 VALUES (NULL);           -- 惊讶:NULL 居然能重复!(NULL 不等于 NULL)

-- 组合 UNIQUE
CREATE TABLE t2 (a INT, b INT, UNIQUE(a, b));
INSERT INTO t2 VALUES (1, 2);
INSERT INTO t2 VALUES (1, 3);           -- a 重复但组合不同,成功
INSERT INTO t2 VALUES (1, 2);           -- 组合撞车,报错

第二个「NULL 能插两次」是本节最反直觉的点——NULL 与 NULL 不相等,所以不算重复。

五、30 秒实验

把 UNIQUE 去掉再插入重复邮箱——顺利入库。此时表里已埋下两条重复数据,回头再想清理就麻烦了:约束要建在灌数据之前。

六、常见误区

自测三问 1. UNIQUE 和主键两个最大区别?(可 NULL、可有多个) 2. 同一学生同一科目只许一条成绩,怎么建?(组合 UNIQUE(a, b)) 3. 为什么两个 NULL 不算重复?(NULL 互不相等,比较结果未知)

相关笔记