web-dev-qa-db-ja.com

Postgresql:条件付き一意制約

テーブルの一部の列にのみ一意性を適用する制約を追加したいと思います。

ALTER TABLE stop ADD CONSTRAINT myc UNIQUE (col_a) WHERE (col_b is null);

上記のWHERE部分は希望的観測です。

これを行う方法はありますか?または、リレーショナルドローイングボードに戻る必要がありますか?

83
EoghanM

PostgreSQLは部分(つまり条件付き)UNIQUE制約を定義しません-ただし、あなたはcan部分的な一意index。 PostgreSQLは一意のインデックスを使用して一意の制約を実装しているため、効果は同じで、information_schemaにリストされている制約は表示されません。

CREATE UNIQUE INDEX stop_myc ON stop (col_a) WHERE (col_b is null);

部分インデックス を参照してください。

140
Craig Ringer

pGは部分(つまり条件付き)UNIQUE制約を定義しないと既に言われています。また、ドキュメントには、テーブルに一意の制約を追加するための好ましい方法はADD CONSTRAINT一意のインデックス

テーブルに一意の制約を追加する好ましい方法は、ALTER TABLE ... ADD CONSTRAINTです。一意の制約を強制するためのインデックスの使用は、直接アクセスすべきではない実装の詳細と見なすことができます。ただし、一意の列に手動でインデックスを作成する必要がないことに注意してください。そうすると、自動的に作成されたインデックスが複製されます。

Exclusion Constraints を使用して実装する方法があります(このソリューションの@dukelionに感謝します)

あなたの場合、それは次のようになります

ALTER TABLE stop
    ADD CONSTRAINT stop_col_a_key_part EXCLUDE (col_a WITH =) WHERE (col_b IS null);
20
Peter Yeremenko