12

PostgreSQLで条件付きで外部キーを追加することは可能ですか?

何かのようなもの:ALTER TABLE table1 ADD FOREIGN KEY (some_id) REFERENCES other_table WHERE some_id NOT IN (0,-1) AND some_id IS NOT NULL;

具体的には、私の参照テーブルにはすべて正の整数(1+)がありますが、外部キーを追加する必要があるテーブルには、代わりにゼロ(0)、ヌル、および負の1(-1)を含めることができます。

ノート:

これは貧弱なテーブルデザインであることを十分に認識していますが、この時点で利用できる機能とリソースが存在しなかった10年以上前に構築された巧妙なトリックでした。このシステムは何百もの小売店を運営しているため、この時点で方法を変更して戻ると、私たちが持っていない数か月かかる可能性があります。

トリガーを使用できません。これは外部キーを使用して実行する必要があります。

4

5 に答える 5

5

簡単な答えはノーです。Postgresには条件付き外部キーがありません。検討する可能性のあるいくつかのオプションは次のとおりです。

  1. FK制約がないだけです。このロジックをデータアクセス層に移動し、参照整合性なしで稼働します。
  2. 列で許可NULLします。これは、FK制約がある場合でも完全に有効です。次に、別の列を使用して、との意味を格納し0ます-1
  3. 0およびの参照テーブルにダミー行を追加します-1。偽のデータがあったとしても、FK制約を満たします。

お役に立てれば!

于 2012-06-05T16:07:46.827 に答える
3

table1クリーンアップされた値(0および以外のすべて)を保持する別の「シャドウ」列を追加できます-1。この列は、参照整合性チェックに使用します。table1このシャドウ列は、シャドウ列以外のすべての値を書き込む0単純なトリガーによって更新/入力され-1ます。との両方0-1マップできますnull

次に、参照整合性と変更されていない元の列があります。欠点:トリガーと冗長データも少しあります。しかし、残念ながら、これはレガシースキーマの運命です!

于 2012-06-05T17:42:56.283 に答える
2

要件は、このチェック制約と同等です。

create table t (a float check (a >= -1 and a = floor(a) or a is null));
于 2012-06-05T16:33:11.013 に答える
2

これは、チェック制約と外部キーを使用して実装できます。

CREATE TABLE table1 (some_id INT, some_id_fkey INT REFERENCES other_table(other_id), CHECK (some_id IN (0,-1) OR some_id IS NOT DISTINCT FROM some_id_fkey));

(未検証)

于 2017-04-18T00:41:14.430 に答える
1

別の可能性があります。PG継承を使用して、テーブルのパーティションをフラグ列の+1などに強制します。(これを維持するための通常のルール/トリガー。)次に、Has_PLUS_ONE子テーブルと参照テーブルのみの間にFK関係があります。

于 2012-06-08T21:56:19.083 に答える