11

Postgres 表中有一个列status只能取两个值:ActiveInactive

其中一列名为userid。该表可以有多个相同的行,userid但最多其中一个可以有status = 'Active'. status我只需要一个或不需要Active一个userid。如何使用此条件创建约束?我无法从 Postgres 文档中找到任何帮助。

4

1 回答 1

17

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'

于 2015-12-28T14:46:06.887 回答