微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

database – 添加约束以使每列行唯一

Postgres表中有一个列状态,只能有两个值:Active和Inactive.

其中一列名为userid.该表可以具有多个具有相同用户标识的行,但最多其中一个可以具有status =’Active’.每个用户ID我只需要一个或没有Active状态.如何使用此条件创建约束?我在Postgres文档中找不到任何帮助.

解决方法

@lad2025 commented一样,状态应该是 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,您仍然可以使用此方法.但这实际上会产生一个更大的索引,包括所有行.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐