【发布时间】:2013-06-17 10:21:59
【问题描述】:
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 约束有关吗?有没有更好的方法来做到这一点?
感谢您的帮助!
【问题讨论】:
标签: sql postgresql database-schema