1つの列に特定の値がある場合にのみ適用されるカスタムの一意の列制約


19

次のようにカスタムの一意の列制約を持つことは可能ですか?2つのcol subsettype、両方の文字列があると仮定します(データ型はおそらく重要ではありませんが)。

Ifはtype「真」である、私はの組み合わせをしたいtypesubset一意です。それ以外の場合、制約はありません。DebianでPostgreSQL 8.4を使用しています。


回答:


31

つまり、次のsubset場合に一意になりますtype = 'true'部分的に一意のインデックスは、それを行います。

CREATE UNIQUE INDEX tbl_some_name_idx ON tbl (subset) WHERE type = 'true';

この方法NULLでは、一意の組み合わせを作成することもできますが、それ以外の場合は不可能です-この関連する回答で詳細に説明されているように:
PostgreSQLの複数列の一意制約とNULL値


ありがとうアーウィン。ドキュメントを見たときにこのオプションが表示されませんでした。より直接的なリンクはpostgresql.org/docs/current/interactive/indexes-partial.htmlです。例11-3を参照してください。
ファヒームミタ

@FaheemMitha:あなたがする必要があるので、私は、1つのレベルの高いリンク結合部分インデックスユニークインデックスを
アーウィンブランドステッター

1
@Erwinそのページ(部分インデックスについて)には、部分ユニークインデックスの例があります。
ypercubeᵀᴹ

@ypercube:ああ、そうだね。それがより良いリンクです。その最後の章を指すように答えを変えました。
アーウィンブランドステッター

6

これは上記のErwinの答えを補足するものですが、PostgreSQLはさまざまな種類のインデックスをサポートしています。これらは一般的に相互に排他的ではありません。これらは次のように考えることができます。

  • インデックスメソッド(btree、GiST、GINなど)。必要に応じて1つを選択します(btreeがデフォルトです)
  • 部分的または完全。where句を部分的に使用する場合
  • 直接または機能的。関数の出力にインデックスを付けることができます。
  • 一意または非一意

これらはすべて、さまざまな方法で組み合わせることができます。ここで行っていることは、ユニークで部分的な機能を使用することです。これにより、部分的にユニークなインデックスが得られます(これは、発見する際に非常に便利です)。

ただし、typeがtrueであるサブセットフィールドに、大文字と小文字を区別しないインデックスを作成するとします。次に、機能定義を追加します。

CREATE INDEX my_index_name_idx_u ON tbl (lower(subset)) WHERE type;

これにより、typeがtrueであるサブセット属性で呼び出されるlower()関数の出力に一意のインデックスが作成されることに注意してください。


アーウィンの答えのインデックスは直接的ですが、あなたの例のインデックスは機能的で正しいですか?
ファヒームミタ

@FaheemMitha:正しい。
アーウィンブランドステッター
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.