其中一列名为userid.该表可以具有多个具有相同用户标识的行,但最多其中一个可以具有status =’Active’.每个用户ID我只需要一个或没有Active状态.如何使用此条件创建约束?我在Postgres文档中找不到任何帮助.
解决方法
boolean
.更便宜,更清洁.
无论哪种方式,您都可以使用partial unique index强制执行规则:
要在整个表中允许零或一行,状态=’活动’:
CREATE UNIQUE INDEX tbl_active_uni ON tbl (status) WHERE status = 'Active';
要为每个用户标识允许零或一行,状态=’活动’,请将userid设为索引列:
CREATE UNIQUE INDEX tbl_userid_active_uni ON tbl (userid) WHERE status = 'Active';
请注意,userid IS NULL不会触发唯一的违规,因为两个NULL值永远不会被视为相等.在这种情况下,userid必须是set NOT NULL
.
> How to add a conditional unique index on PostgreSQL
> Create unique constraint with null columns
为什么索引而不是约束?
解决你的question in the comment:这是一个索引,而不是CONSTRAINT
.
第一种情况的索引很小,只有一行或没有行.
第二种情况的索引每个现有用户ID占一行,但它是最便宜和最快的方式,除了干净和安全.在任何情况下,您都需要一个索引来检查其他行以使其快速.
您不能对其他行进行CHECK约束检查 – 至少不能以干净,可靠的方式检查.对于这种情况,我肯定不会推荐一些方法:
> Trigger vs. check constraint
> How to avoid a cyclic dependency (circular reference) between 3 tables?
> Disable all constraints and table checks while restoring a dump
如果对(userid,status)使用UNIQUE约束(在后台也使用唯一索引实现!),则不能使其成为局部,并且所有组合都被强制为唯一.如果您对除“活动”案例之外的所有情况使用状态IS NULL,您仍然可以使用此方法.但这实际上会产生一个更大的索引,包括所有行.