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
一意ごとに 1 つの行のみが"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 制約でこの種の除外は可能ですか? これを行うより良い方法はありますか?
助けてくれてありがとう!