PostgreSQL CHECK 与 UNIQUE 约束教程
CHECK 约束限制列的取值规则,UNIQUE 约束保证列(或列组合)不出现重复值。两者都是保证数据质量的基础手段。
本篇内容
- CHECK 约束:单列与表级表达式
- UNIQUE 约束与唯一索引
- NULL 在唯一约束中的行为(多个 NULL 不冲突)
- 部分唯一 / 表达式唯一
CHECK 约束
-- 列级
CREATE TABLE users (
age INTEGER CHECK (age >= 0 AND age < 150),
status SMALLINT CHECK (status IN (0, 1, 2))
);
-- 表级(可跨列)
CREATE TABLE orders (
amount NUMERIC CHECK (amount > 0),
discount NUMERIC,
CONSTRAINT orders_discount_check CHECK (discount >= 0 AND discount <= amount)
);
UNIQUE 约束
-- 单列唯一
CREATE TABLE users (
email VARCHAR(255) UNIQUE
);
-- 组合唯一:(user_id, tag) 不能重复
CREATE TABLE user_tags (
user_id BIGINT,
tag VARCHAR(50),
UNIQUE (user_id, tag)
);
部分唯一与表达式唯一
-- 只对未软删除的行要求邮箱唯一(多个已删除行可共享邮箱)
CREATE UNIQUE INDEX users_email_uidx ON users (email)
WHERE deleted_at IS NULL;
-- 按表达式建唯一索引:不区分大小写的邮箱
CREATE UNIQUE INDEX users_email_lower_uidx ON users (lower(email));
待补充(TODO)
- 补充:约束 vs 唯一索引的区别与维护方式(ALTER TABLE … ADD CONSTRAINT … USING INDEX)
- 补充:添加约束时已有脏数据导致的失败与清理步骤
- 补充:NOT VALID + VALIDATE 的在线添加方式
- 补充:CHECK 约束中不能使用子查询/函数的限制