PostgreSQLでis_anonymousがtrueの時だけemailをNULLにするCHECK制約

  • PostgreSQL
  • SQL

この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。

何が起きたか

あるテーブルで、特定のカラム(is_anonymous)がtrueの時だけ、別カラム(email)がNULLであることを保証したいケースがあった。こういう条件付きの制約がCHECK制約で書けるか気になったので確認した。

結論

以下で書ける。

ALTER TABLE users
ADD CONSTRAINT check_anonymous_email_null CHECK (
NOT is_anonymous OR email IS NULL
);

is_anonymousがtrueの時だけemail IS NULLが要求される。is_anonymousがfalseまたはNULLの場合は制約に抵触しない。

emailとphoneの両方をNULLにしたい場合はこう。

ALTER TABLE users
ADD CONSTRAINT check_anonymous_contact_null CHECK (
NOT is_anonymous OR (email IS NULL AND phone IS NULL)
);

こちらも同じロジックの拡張で、is_anonymousがtrueの時だけ両方NULLが要求される。

注意点

この書き方はis_anonymousカラムがNULL許容(NOT NULL制約なし)であることが前提。CHECK制約はNULL評価も「通過」扱いになるので、is_anonymousがNULLのケースでも制約には抵触しない。

もしis_anonymousがNOT NULLで定義されているならNOT is_anonymous OR ...だけで十分で、NULLのケースを気にする必要はない。