联合唯一约束
联合唯一约束要求一组列的组合值唯一,而不是要求每个参与列分别唯一。
#concept
#growing
#backend
#database
#sql
[!info] related notes
- 所属 MOC: database-moc
- 前置概念: constraint、primary-key
- 并列概念: many-to-many-relationship
- 易混淆概念:
- 关系笔记: primary-key-foreign-key-and-constraints
联合唯一约束
一句话定义
联合唯一约束要求若干列组成的“组合键”不能重复,但允许每一列单独出现重复值。
核心机制
UNIQUE (user_id, slug)
表示:
(user_id, slug)
这个组合必须唯一,而不是 user_id 和 slug 各自唯一。
例如:
user_id | slug
--------|------
1 | hello ✅
2 | hello ✅
1 | world ✅
1 | hello ❌
这非常适合表达“同一个用户内部唯一,但不同用户之间可以重复”的业务规则。
常见场景
(user_id, slug):同一作者不能重复使用 slug。(student_id, course_id):同一学生不能重复选同一课程。(order_id, product_id):一张订单中同一商品只保留一条明细时。(tenant_id, email):多租户系统中邮箱只要求租户内唯一。
与复合主键的区别
PRIMARY KEY (a, b) 同样要求组合唯一且非空,并把该组合作为行的主身份;UNIQUE (a, b) 只增加候选唯一性,表仍可以使用独立 id 作为主键。
NULL 边界
唯一约束和 NULL 的语义依数据库而异。以 PostgreSQL 常规 UNIQUE 为例,多个 NULL 通常可以共存,因为 NULL 不被视为彼此相等。业务要求字段必须参与唯一身份时,应同时考虑 NOT NULL 或数据库提供的更精确语义。
设计原则
先用业务语言说清“到底什么组合不能重复”,再决定唯一键。不要为了方便把某一列错误地设成单列 UNIQUE,否则会把合法数据拒绝掉。