database - 添加约束以使每组行的列唯一

标签 database postgresql constraints unique-index partial-index

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

其中一列名为 userid。该表可以有多个具有相同 userid 的行,但其中最多可以有一个 status = 'Active'。对于每个 userid,我只需要一个或不需要 status 作为 Active。我怎样才能用这种条件创建约束?我无法从 Postgres 文档中找到任何帮助。

最佳答案

status 应该是 boolean .更便宜、更清洁。

无论哪种方式,您都可以使用 partial unique index 强加您的规则.

允许在整个表中包含 status = 'Active' 的零行或一行 :

CREATE UNIQUE INDEX tbl_active_uni ON tbl (status)
WHERE status = 'Active';

要允许 status = 'Active' 的零行或一行 per userid,使 userid 索引列:

CREATE UNIQUE INDEX tbl_userid_active_uni ON tbl (userid)
WHERE status = 'Active';

请注意,userid IS NULL 不会触发唯一违规,因为两个 NULL 值永远不会被视为相等。 userid 必须是 set NOT NULL在这种情况下。

为什么使用索引而不是约束?

解决您的 question in the comment : 这是索引,不是 CONSTRAINT .

第一种情况的索引很小,包含一行或没有行。
第二种情况的索引为每个现有 userid 保留一行,但它是最便宜和最快的方式,而且干净和安全。在任何情况下,您都需要一个索引来检查其他行以加快速度。

您不能对其他行进行 CHECK 约束检查 - 至少不能以干净、可靠的方式进行检查。对于这种情况,我肯定不推荐有一些方法:

如果你在 (userid, status) 上使用了 UNIQUE 约束(它在内部也是用唯一索引实现的!),你不能让它部分,并且所有组合都被强制为唯一的。如果您对除 'Active' 情况之外的所有情况使用 status IS NULL,您仍然可以使用它。但这实际上会强加一个更大的索引,包括所有行。

关于database - 添加约束以使每组行的列唯一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34495479/

相关文章:

database - 创建一个双向的多对多关联,带有额外的学说字段

mysql时间戳不显示天数

database - 将用户上传的文件存储在网络服务器上

ruby-on-rails - 在迁移 PostgreSQL 上设置主键值 0 并自动递增

java - Spring JDBC 中区分唯一键约束异常和主键约束异常

iphone - 排除 iPhone3GS 及以下版本下载我的应用程序

database - 如何设计一个高效支持多键查询的数据库?

postgresql - Postgres 选择连接的列名

sql - 如何使用 PostgreSQL 序列更新 SQL 中的唯一值?

iOS 7 - Autolayout - 如何在旋转时更改 View 的位置