Postgres表格中有一列status
,只有两个值:Active
和Inactive
。
其中一列名为userid
。该表可以包含多个具有相同userid
的行,但最多只能有一行status = 'Active'
。每status
我只需要一Active
userid
<%= render partial: 'vote', locals: {:@post => post} %>
。如何使用此条件创建约束?我无法从Postgres文档中找到任何帮助。
答案 0 :(得分:8)
与@lad2025 commented一样,status
应该是boolean
。更便宜,更清洁。
无论哪种方式,您都可以使用partial unique index:
强制执行规则要在整个表格中使用status = 'Active'
允许零行或一行 :
CREATE UNIQUE INDEX tbl_active_uni ON tbl (status)
WHERE status = 'Active';
要使status = 'Active'
每userid
允许零行或一行,请将userid
设为索引列:
CREATE UNIQUE INDEX tbl_userid_active_uni ON tbl (userid)
WHERE status = 'Active';
请注意userid IS NULL
不会触发唯一的违规,因为两个NULL值永远不会被视为相等。 <{1}}在这种情况下必须是set NOT NULL
。
解决您的question in the comment:这是一个索引,而不是CONSTRAINT
。
第一种情况的索引是 很小 ,只保留一行或没有行。
第二种情况的索引每个现有userid
占一行,但它是 最便宜和最快的方式 ,除了干净和安全。在任何情况下,您都需要一个索引来检查其他行以使其快速。
您不能对其他行进行userid
约束检查 - 至少不能以干净,可靠的方式进行检查。对于这种情况,有些方法我肯定不推荐:
如果您在CHECK
上使用UNIQUE
约束(后台也使用唯一索引实现!),则无法使其成为 partial 和所有组合都被强制为唯一。如果您使用(userid, status)
处理除status IS NULL
案例之外的所有情况, 仍然可以使用此功能。但这实际上会产生更大的索引,包括所有行。