Postgres 表中有一个列status
只能取两个值:Active
和Inactive
。
其中一列名为userid
。该表可以有多个相同的行,userid
但最多其中一个可以有status = 'Active'
. status
我只需要一个或不需要Active
一个userid
。如何使用此条件创建约束?我无法从 Postgres 文档中找到任何帮助。
Postgres 表中有一个列status
只能取两个值:Active
和Inactive
。
其中一列名为userid
。该表可以有多个相同的行,userid
但最多其中一个可以有status = 'Active'
. status
我只需要一个或不需要Active
一个userid
。如何使用此条件创建约束?我无法从 Postgres 文档中找到任何帮助。
status
应该是真的boolean
。更便宜,更干净。
无论哪种方式,您都可以使用部分唯一索引强加您的规则。
status = 'Active'
要在整个表中允许零行或一行:
CREATE UNIQUE INDEX tbl_active_uni ON tbl (status)
WHERE status = 'Active';
status = 'Active'
要使用peruserid
允许零行或一行,请创建userid
索引列:
CREATE UNIQUE INDEX tbl_userid_active_uni ON tbl (userid)
WHERE status = 'Active';
请注意,userid IS NULL
这不会触发唯一违规,因为两个 NULL 值永远不会被视为相等。在这种情况下userid
必须设置。NOT NULL
在评论中解决您的问题:这是一个索引,而不是CONSTRAINT
.
第一种情况的索引是tiny,包含一行或没有行。
第二种情况的索引每个现有的保留一行userid
,但除了干净和安全之外,它是最便宜和最快的方式。在任何情况下,您都需要一个索引来检查其他行以加快速度。
您不能CHECK
对其他行进行约束检查 - 至少不能以干净、可靠的方式进行。对于这种情况,我当然不建议使用以下方法:
如果您使用UNIQUE
约束(userid, status)
(这也是在内部使用唯一索引实现的!),则不能使其成为partial,并且所有组合都被强制为唯一。如果您处理除案例之外的所有案例,您仍然可以使用它。但这实际上会强加一个更大的索引,包括所有行。status IS NULL
'Active'