回答:
SQL Serverを使用すると、多くの愚かなことができます。
すべての行がそれ自体の制約を満たすため、これに違反することは決してできないという事実にもかかわらず、それ自体を参照する列に外部キーを作成することもできます。
同じ関係で2つの外部キーを作成する機能が役立つ可能性がある1つのエッジケースは、外部キーの検証に使用されるインデックスが作成時に決定されるためです。より良い(つまり、より狭い)インデックスが後で発生した場合、これにより、新しい外部キー制約がより良いインデックスにバインドされて作成され、元の制約はアクティブな制約のないギャップなしで削除されます。
(以下の例のように)
CREATE TABLE T1(
T1_Id INT PRIMARY KEY CLUSTERED NOT NULL,
Filler CHAR(4000) NULL,
)
INSERT INTO T1 VALUES (1, '');
CREATE TABLE T2(
T2_Id INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
T1_Id INT NOT NULL CONSTRAINT FK REFERENCES T1 (T1_Id),
Filler CHAR(4000) NULL,
)
ALTER TABLE T1 ADD CONSTRAINT
UQ_T1 UNIQUE NONCLUSTERED(T1_Id)
/*Execution Plan uses clustered index*/
INSERT INTO T2 VALUES (1,1)
ALTER TABLE T2 WITH CHECK ADD CONSTRAINT FK2 FOREIGN KEY(T1_Id)
REFERENCES T1 (T1_Id)
ALTER TABLE T2 DROP CONSTRAINT FK
/*Now Execution Plan now uses non clustered index*/
INSERT INTO T2 VALUES (1,1)
DROP TABLE T2, T1;
一時的な制約として、両方の制約が存在する間、挿入はいずれも両方のインデックスに対して検証されます。
同じ外部キー制約を使用することはできません。つまり、同じ列にあり、同じテーブルと列を参照します。
同じチェックを2回以上繰り返すようなものです。
同じ列に50のインデックスを作成し、2番目のログファイルを追加し、最大サーバーメモリを20MBに設定できる同じ理由...ほとんどの人はこれらのことを行わないでしょうが、それらを時々行う正当な理由があるため、エンジンにオーバーヘッドを作成して、単に不適切なことしか行われていないものに対するチェックを追加することでメリットが得られます。
青緑色のように聞こえます。
青から緑に切り替わり始めたら、一時的に追加のコピーを作成する必要があります。
私たちがしたいことは、一時的に追加の外部キーCHECK WITH NOCHECK
を作成することON UPDATE CASCADE ON DELETE SET NULL
です。これが行うことは、動作する外部キーですが、キーの作成時に既存の行はチェックされません。
後で一致するはずのすべての行をクリーンアップした後、コマンドオプションなしで新しい外部キーを作成し(デフォルトはCHECK WITH CHECK
通常必要なものです)、一時的な外部キーを削除します。
外部キーを削除して再作成した場合、一部のガベージ行がスリップする可能性があることに注意してください。