在 PostgreSQL 中实现 lck
, special
, item
与 org_id
或 user_id
组合唯一的约束
要实现 lck
, special
, item
这三个字段必须与 org_id
或 user_id
中的一个(但不能同时)组合唯一的约束,你需要创建以下约束:
方案1:使用两个唯一约束 + 检查约束
ALTER TABLE hs_charging
-- 确保 org_id 和 user_id 不同时为 NULL 且不同时有值
ADD CONSTRAINT org_or_user_check CHECK ((org_id IS NOT NULL AND user_id IS NULL) OR(org_id IS NULL AND user_id IS NOT NULL)
);-- 为 org_id 组合创建唯一约束
ALTER TABLE hs_charging
ADD CONSTRAINT unique_with_org UNIQUE (lck, special, item, org_id)
WHERE org_id IS NOT NULL;-- 为 user_id 组合创建唯一约束
ALTER TABLE hs_charging
ADD CONSTRAINT unique_with_user UNIQUE (lck, special, item, user_id)
WHERE user_id IS NOT NULL;
方案2:使用部分索引实现(更简洁)
-- 确保 org_id 和 user_id 只能填一个
ALTER TABLE hs_charging
ADD CONSTRAINT org_or_user_check CHECK ((org_id IS NULL) <> (user_id IS NULL)
);-- 为 org_id 情况创建唯一部分索引
CREATE UNIQUE INDEX unique_with_org ON hs_charging (lck, special, item, org_id)
WHERE org_id IS NOT NULL;-- 为 user_id 情况创建唯一部分索引
CREATE UNIQUE INDEX unique_with_user ON hs_charging (lck, special, item, user_id)
WHERE user_id IS NOT NULL;
说明
CHECK
约束确保org_id
和user_id
有且只有一个有值- 两个唯一约束/索引分别处理两种情况:
- 当使用
org_id
时,lck
,special
,item
,org_id
组合必须唯一 - 当使用
user_id
时,lck
,special
,item
,user_id
组合必须唯一
- 当使用
- 使用
WHERE
子句的部分索引/约束可以更高效地实现这种条件唯一性
方案2使用部分索引通常更受推荐,因为它更灵活且性能更好。