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

相关文章

项目需要,有个数据需要导入,拿到手一开始以为是mysql,结果...
本文小编为大家详细介绍“怎么查看PostgreSQL数据库中所有表...
错误现象问题原因这是在远程连接时pg_hba.conf文件没有配置正...
因本地资源有限,在公共测试环境搭建了PGsql环境,从数据库本...
wamp 环境 这个提示就是说你的版本低于10了。 先打印ph...
psycopg2.OperationalError: SSL SYSCALL error: EOF detect...