2013-02-21 16 views
11

違いは何ですか?私はこの2つのテーブルがある場合:親テーブルまたは子テーブルに外部キーを作成する必要がありますか?

CREATE TABLE Account (Id int NOT NULL) 

CREATE TABLE Customer (AccountId int NOT NULL) 

をそして私は、私がすべき以下の2、そしてなぜをリンクする外部キーをしたいですか?

オプション1:

ALTER TABLE [dbo].[Customer] WITH CHECK 
    ADD CONSTRAINT [FK_Accounts_Customers] FOREIGN KEY([AccountId]) 
    REFERENCES [dbo].[Account] ([Id]) 

オプション2:

ALTER TABLE [dbo].[Account] WITH CHECK 
    ADD CONSTRAINT [FK_Accounts_Customers] FOREIGN KEY([Id]) 
    REFERENCES [dbo].[Customer] ([Id]) 
+0

私は通常、他のものがなければ生きられないテーブル(それが当てはまる場合)に置きます。しかし、データの概念的な観点からはどんな意味があるとしても、問合せを簡単にするものに依存します。これらの2つのwhateversは反対でもあります。 – entonio

答えて

1

私は子から親に外部キーを使用します。 tell taleの質問は、エンティティの1つを削除する必要がある場合はどうなりますか?

+0

この場合、顧客を削除するとアカウントにカスケードするのではなく、アカウントを削除するとカスケードする必要があります。 – scottm

+1

アカウントは顧客なしでも生きることができますが、顧客はアカウントで生きることができません。したがって、顧客はアカウントを指すべきであり、他の方法では指し示すべきではない。 - > Option 1 –

+1

@scottmカスケードを処理するDELETEプロシージャーにロジックを書き込む必要があります。私はSQL Serverで現在利用可能なON CASCADEオプションの大ファンではなく、本当に信頼しません。 –

4

コンテキストによって異なります。すべての顧客にクライアントがいますか?どちらが親ですか? Accountに複数のCustomersがあるようです。この場合、参照はCustomerテーブルに属します。今

、それはどこにでも実体CustomerIDAccountIDに電話してください、と述べました。プライマリテーブルでは重複しているように見えるかもしれませんが、名前はモデル全体で一貫していなければなりません。

+5

名前付けに関する1000%の合意。 PKのフィールド名としてIDを使用すべきではありません。常にエンティティ名を接頭辞として使用してください。これは、コンベンションベースのマッピングを使用するORMを使用する場合に特に重要です。これは、モデルがどのように見えるかを期待するためです。欠点は、結合を書くときにオブジェクトを修飾しなければならないということですが、 'a)'とにかくこれを行うべきですし、ORMを使って 'b 'を使うと、多分/ T-SQLをあまり書くことはないでしょう – Charleh

+2

Rails&rails-inspiredフレームワークは真実ではありません。その場合、idが主キーである場合、それは 'customers.id'のような 'id'だけです - それは十分明白です。 foreign_keyとして参照されている場合は、 'accounts.customer_id'を行います。 – konung

0

FK(外部キー)をカラムリストの下位行は、他の場所でカラムリストの下位行の値として表示されなければならないの値DBMSに伝えます。それが起こるときはいつでも(それは他の宣言によって既に暗示されていません)、FKを宣言します。あなたがCASCADEアクションを参照しているテーブルに変更したときに参照されたテーブルに適用したい場合は、そのテーブルを宣言します。

(それは非FKの場面のために提供することができませんでしたCASCADEについての特別なものは何もありません。それはちょうどFKSで頻繁に来て、合理的にそれらの相互作用を制限することにより、FKSの明示的なグラフがあります。)

FK cycleがある場合は、トリガーを使用する必要があります。どの制約が宣言的に適用されるかについてのあなたの決定&トリガーは、(望ましい)制約のグラフを考慮する必要があります。