web-dev-qa-db-ja.com

テーブルがその主キーをそれ自体への外部キーとして使用する理由

データベースを調べていると、主キーを外部キーとして使用しているテーブルに出くわしました。

テーブルが階層構造を構築するためにそれ自体への外部キーを持つことができることを見てきましたが、主キーを参照するために別の列を使用します。

主キーは一意であるため、この状況では、行はそれ自体を指すことしかできないのではないでしょうか?これはトートロジーのリンクのようです。なぜなら、すでに行がある場合は、すでに行があるからです。

これが行われる理由はありますか?

Table joined to itself

同じテーブルと列が定義の両方の半分で使用されているため、制約がそのように記述されていることは確かです(図を見るだけではありません)。

22
Aaroninus

あなたが言ったように。 A FOREIGN KEY同じテーブルを参照する制約は通常、階層構造用であり、主キーを参照するために別の列を使用します。良い例は従業員のテーブルです:

EmployeeId    Int     Primary Key
EmployeeName  String
ManagerId     Int     Foreign key going back to the EmployeeId

したがって、この場合、テーブルからそれ自体への外部キーがあります。すべてのマネージャーは従業員でもあるため、ManagerIdは実際にはマネージャーのEmployeeIdです。

一方、もし誰かがEmployeeIdをEmployeeテーブルへの外部キーとして使用したということであれば、おそらく間違いでしたです。私はテストを実行しましたが、それは可能ですが実際には使用されません

CREATE TABLE Employee (EmployeeId Int PRIMARY KEY,
                        EmployeeName varchar(50),
                        ManagerId Int);


ALTER TABLE Employee ADD CONSTRAINT fk_employee 
    FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId);
29
Kenneth Fisher

私は自分のdbでそのような外部キーを見つけただけで、自分で作成したに違いありません。これは偶然に起こったと思います。 (Management Studio、SQL 2014 Express内で)主キーのあるテーブルのコンテキストメニューで[新しい外部キー]をクリックすると、それ自体を参照する外部キーが既に自動的に作成されます。下記参照:

enter image description here

新しいものを追加するのではなく、変更する必要があることに気付かない場合は、そのまま残ります。または、[閉じる]ボタンをクリックするだけで[キャンセル]のようになる場合でも、テーブル定義を保存した後も外部キーが作成されます。

したがって、私にとって、このような外部キーは意味がなく、削除することができます。

6
Stefan Müller

おそらく、設計者はTRUNCATE TABLEの使用を無効にしたいと考えていましたか?

TRUNCATE TABLEは、外部キー制約があるテーブルでは使用できません別のテーブルへですがcanある場合に使用できます自己参照 =外部キー。 TRUNCATE TABLE(Transact-SQL) のドキュメントから:

BOL Extract

DELETE句のないWHEREステートメントは、TRUNCATE TABLE(テーブル内のすべての行を削除)と同様の効果がありますが、DELETEステートメントは削除トリガーを起動します。 DELETEは許可するが、TRUNCATE TABLEは許可しない理由かもしれません。

私は権限を使用してこれを行います(DELETEには削除権限が必要、TRUNCATE TABLEにはテーブル変更権限が必要です)が、設計者がこれを実行できなかった理由があるのでしょうか?

注:設計者が行ったことで実際にTRUNCATE TABLEの使用が無効になるわけではありませんが、これは彼らの意図であると推測しています。

4