1

これは、PostgreSQLの実際の問題を説明するおもちゃの例です。以下の例ではPostgreSQL8.4.3サーバーを使用していますが、他のバージョンでも同じ問題が発生していると思われます。

次の表があるとします。

=>テーブルtmp_fooを作成します(fooブール値はnull固有ではなく、barブール値はnull固有ではありません);
=> tmp_foo(foo、bar)の値(true、true)、(false、false);に挿入します。
=> select * from tmp_foo;
 foo | バー
----- + -----
 t | t
 f | f

テーブルを次のように変更できますか?

=> select * from tmp_foo;
 foo | バー
----- + -----
 t | f
 f | t

行を削除したり、テーブルスキーマを変更したりせずに?これ:

=>更新tmp_fooセットバー=バーではありません;
エラー:重複するキー値が一意の制約「tmp_foo_bar_key」に違反しています

動作しません。

削除が許可されている場合、これは次のとおりです。

=>一時テーブルtmp_foo_2をselect*fromtmp_fooとして作成します。
=>更新tmp_foo_2setbar = not bar;
=>tmp_fooから削除します;
=>tmp_fooに挿入select*from tmp_foo_2;

動作します。これはこの例の最も単純な解決策ではありませんが、より複雑な例に簡単に一般化できます。

4

1 に答える 1

3

これを行うには、延期可能な一意の制約が必要です。

各列には、できるだけ多くの一意の値があります。したがって、任意の行を変更するには、一部の行が一時的に一意の制約に違反するか、一部の行を削除して制約に違反しないようにする必要があります。延期可能な一意の制約により、前者の一時的な違反(トランザクション内)を実行できます。

ここまで進んで、それが正しいように聞こえる場合、あなたの質問に対する答えはPostgresのバージョンによって異なります。

8.4までのPostgresは、外部キー制約の延期のみを許可します。当然の結果として、固有の制約を延期することはできません。

Postgres 9.0ベータは、理論的には延期可能な固有の制約を提供します。自分で試したことはありませんが、この機能は久しぶりなので、実装を決めたときにうまくいったと思います。

これは、9.0の固有のインデックスとに関連するドキュメントの2つのモーゼルですSET CONSTRAINTS。後者のリンクでわかるように、固有の制約はSET CONSTRAINTS、9.0のドキュメントで延期をサポートするものとして明示的にリストされています。この新機能についてはまだ調べていません。セマンティクスが正確に必要なものであることを保証することはできません。しかし、それはただのことのようです。

于 2010-07-20T22:46:07.743 に答える