PostgreSQLで論理削除(NULL許容カラムがある)テーブルにユニーク制約を貼り、UPSERT(ON CONFLICT)する

最終更新日

development

対象環境

  • PostgreSQL 9.5以上
    • ON CONFLICTが対応しているもの
  • Nullableなカラムを含めてユニーク制約を貼らなければならないテーブルがある

前提

  • 正しくないアプローチだったらごめんなさい
  • パフォーマンスに関しては未確認です

結論

ユニーク制約を貼る

ユニーク制約がないとUPSERTできないので、下記のようにCOALESCEを使ってNULL許容カラムにデフォルト値を入れてユニーク制約を貼ります。
※ COALESCEは第一引数がNULLの時、第二引数の値を返す。NULLじゃない時は第一引数の値を返す関数です。

COALESCE使わないとPostgreSQLはNULL<>NULLなので、同じメールアドレスで何レコードもINSERT出来てしまいます。
そこで、COALESCEを使うことで論理削除テーブルにも正しくユニーク制約を貼れると思います。

UPSERTする

UPSERTする場合は、下記のようにCONFLICT句にもCOALESCEを適用してクエリを書きます。

varcharやint型でも同様に''0を使うことでNullableなカラムにユニーク制約が貼れそうです。

あとがき

  • PostgreSQLはNULL<>NULL

↑があるため、これまで自分は論理削除テーブルにはユニーク制約は貼らずに、アプリケーション側でユニークになるようにバリデーションをしてました。
ユニーク制約貼りたいのに貼れない方やUPSERTが出来なくて困っている方の役に立てたら嬉しいです。

stmon19

遊びが一番 人生遊び 好きにまみれてます

シェアする