条件付きでいくつかのデータをテーブルに挿入しようとしています。ここでは、列値の各組み合わせがテーブルに表示されるのは最大で1回だけです。スキーマは次のようになります。
CREATE TABLE foobar (
id SERIAL PRIMARY KEY,
a_id INTEGER,
b_id INTEGER,
c_id INTEGER,
ident VARCHAR(32),
date_a timestamp,
date_b timestamp,
FOREIGN KEY a_id REFERENCES a (id) ON DELETE CASCADE,
FOREIGN KEY b_id REFERENCES b (id) ON DELETE CASCADE,
FOREIGN KEY c_id REFERENCES c (id) ON DELETE CASCADE));
(a_id、b_id、c_id、ident)の組み合わせは一意ですが、date_aとdate_bの両方がNULLである行にのみ適用されます。
a_id、b_id、c_id、タスクの組み合わせがまだデータベースにない場合にのみ、新しい行を挿入できるようにしたい。もしそうなら、それは何もする必要はありません。
最初はこれらの列に一意の制約を作成しようとしましたが、問題は、a_id、b_id、およびc_idの少なくとも1つがnullでない限り、それらをNULLにできることです。これにより、固有の制約が台無しになります。a、b、およびc_idフィールドは外部キーであるため、他のスタブ値(-1など)に設定することはできません。
私は(私のより良い判断に反して)ロックで遊んでみましたが、テストから数分以内にデッドロックが発生しました。
この問題の標準的な解決策はありますか?