📄 一句话概括
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 去掉再插入重复邮箱——顺利入库。此时表里已埋下两条重复数据,回头再想清理就麻烦了:约束要建在灌数据之前。
六、常见误区
- 「UNIQUE 列也不能重复塞 NULL」:能塞;NULL 互不相等,数据库不算它重复(要不要拦由 NOT NULL 补刀)
- 「主键和 UNIQUE 只能二选一」:一张表 1 个主键 + N 个 UNIQUE 很常见(id 主键、email UNIQUE、phone UNIQUE)
自测三问
1. UNIQUE 和主键两个最大区别?(可 NULL、可有多个) 2. 同一学生同一科目只许一条成绩,怎么建?(组合 UNIQUE(a, b)) 3. 为什么两个 NULL 不算重复?(NULL 互不相等,比较结果未知)- ☐ 下一节(4-11 AUTO_INCREMENT-自动输入连续的编号)
相关笔记
- NOT NULL-避免数据为空的状态 —— 上一节:拦空值,本节拦重复
- PRIMARY KEY、主关键字、主键-使记录可以进行唯一识别 —— 加强版对比
- 表连接-将各种表组合在一起 —— 主键外键体系的源头
- 🗄️ 数据库基础 · 索引 —— 全课路线图