status
本当にあるはずboolean
です。より安く、よりきれいに。
どちらの方法でも、部分的な一意のインデックスを使用してルールを課すことができます。
status = 'Active'
テーブル全体で 0 行または 1 行を許可するには:
CREATE UNIQUE INDEX tbl_active_uni ON tbl (status)
WHERE status = 'Active';
status = 'Active'
peruserid
で0 行または 1 行を許可するにuserid
は、インデックス付きの列を作成します。
CREATE UNIQUE INDEX tbl_userid_active_uni ON tbl (userid)
WHERE status = 'Active';
userid IS NULL
2 つの NULL 値が等しいとは見なされないため、一意の違反はトリガーされないことに注意してください。この場合、設定userid
する必要があります。NOT NULL
制約ではなくインデックスを使用する理由
コメントで質問に対処する: これはインデックスであり、CONSTRAINT
.
最初のケースのインデックスはtinyで、行を 1 つ保持するか、保持しません。
2 番目のケースのインデックスは、既存の ごとに 1 つの行を保持しますが、クリーンで安全であることに加えて、userid
これが最も安価で最速の方法です。これを高速化するには、いずれにしても他の行をチェックするためのインデックスが必要です。
CHECK
少なくともクリーンで信頼できる方法では、他の行で制約チェックを行うことはできません。この場合、私が絶対にお勧めしない方法があります。
UNIQUE
制約を使用する場合(これも内部的に一意のインデックスで実装されています!)、それをpartial(userid, status)
にすることはできず、すべての組み合わせが一意になるように強制されます。ケースを除くすべてのケースで作業する場合、これを引き続き使用できます。しかし、実際には、すべての行を含むはるかに大きなインデックスが必要になります。status IS NULL
'Active'