Postgres 9.0 支持排除约束,这有点像一般的唯一约束(http://www.postgresql.org/docs/9.0/static/sql-createtable.html#SQL-CREATETABLE-EXCLUDE)。
我认为这可能是解决此问题的好方法,但我无法弄清楚如何正确使用排除约束。
这是问题所在:我有一张这样的表:
CREATE TABLE emails (
id integer NOT NULL,
email character varying(255),
"primary" boolean DEFAULT false,
user_id integer,
);
user_id
我想确保每个唯一的只有一行"primary"
等于 true。我尝试使用这样的排除约束:
ALTER TABLE emails ADD CONSTRAINT one_primary_email_per_user EXCLUDE USING gist (user_id WITH =, "primary" WITH &);
Postgres 拒绝了:
ERROR: data type boolean has no default operator class for access method "gist"
HINT: You must specify an operator class for the index or define a default operator class for the data type.
我再次尝试将布尔列转换为bit
:
ALTER TABLE emails ADD CONSTRAINT one_primary_email_per_user EXCLUDE (user_id WITH =, (case "primary" when 't' then '1'::bit else '0'::bit end) WITH &);
那没有用。它似乎&(bit,bit)
不是操作员类的一部分bit_ops
:
ERROR: operator &(bit,bit) is not a member of operator family "bit_ops"
DETAIL: The exclusion operator must be related to the index operator class for the constraint.
查看http://www.leadum.com/downloads/dbscribe/samples/postgresql/web_modern/opclass/main/790197862.html,似乎bit_ops
只包括排序比较运算符 (>,<,=,>=,<= ) 而不是位运算符。我不确定为什么会这样。
使用 EXCLUDE 约束可以排除这种情况吗?有一个更好的方法吗?
谢谢您的帮助!