2013-02-21 5 views
11

Was ist der Unterschied? Wenn ich diese beiden Tabellen:Sollte ein Fremdschlüssel in der übergeordneten Tabelle oder untergeordneten Tabelle erstellt werden?

CREATE TABLE Account (Id int NOT NULL) 

CREATE TABLE Customer (AccountId int NOT NULL) 

Und ich möchte einen Fremdschlüssel Verknüpfung der beiden, die der folgenden sollte ich tun, und warum?

Option 1:

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

Option 2:

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

Ich lege es normalerweise auf den einen Tisch, der ohne den anderen nicht leben kann (wenn das zutrifft). Aber es wird davon abhängen, was Ihre Abfragen einfacher macht, was auch immer von einem datenkonzeptuellen Standpunkt aus sinnvoller ist ... und diese beiden Fälle können sogar entgegengesetzt sein. – entonio

Antwort

1

ich einen Fremdschlüssel vom Kind zum Vater verwenden würde. Die Frage ist: Was passiert, wenn Sie eine der Entitäten löschen müssen?

+0

In diesem Fall, wenn ich einen Kunden lösche, möchte ich nicht, dass er zu Konten kaskadiert, aber wenn ich ein Konto lösche, sollte es zu Kunden kaskadieren. – scottm

+1

So kann Konto ohne Kunden leben, aber Kunde kann nicht mit Konto leben. Daher sollte der Kunde auf die Rechnung hinweisen und nicht umgekehrt. -> Option 1 –

+1

@scottm Sie sollten Logik in Ihre DELETE-Prozedur schreiben, die die Kaskade behandelt. Ich bin kein großer Fan von - und nicht wirklich - den ON CASCADE-Optionen, die derzeit in SQL Server verfügbar sind. –

4

Hängt vom Kontext ab. Hat jeder Kunde einen Kunden? Welches ist das Elternteil? Es scheint, als hätte ein Konto mehrere Kunden. In diesem Fall gehört die Referenz in die Kundentabelle.

Nun, das sagte, bitte rufen Sie die Einheiten CustomerID und AccountID überall. Es scheint auf der primären Tabelle redundant zu sein, aber der Name sollte im gesamten Modell konsistent sein.

+5

Eintausend Prozent Zustimmung über die Benennung. Sie sollten ID nicht als Feldnamen für ein PK verwenden - immer mit dem Entitätsnamen als Präfix. Dies ist besonders wichtig bei der Verwendung von ORMs, die konventionsbasiertes Mapping verwenden, da dies häufig der Fall ist, wenn das Modell aussieht. Der Nachteil ist, dass Sie Ihre Objekte beim Schreiben von Joins qualifizieren müssen, aber "a)" sollten Sie dies trotzdem tun und 'b)' mit einem ORM würden Sie wahrscheinlich nicht viel schreiben/irgendein T-SQL – Charleh

+2

Wenn Sie verwenden würden Von Schienen und Schienen inspirierte Frameworks, die nicht stimmen. In diesem Fall, wenn id ein Primärschlüssel ist, ist es nur "id" wie "customers.id" - es ist offensichtlich genug. Wenn Sie als Foreign_key referenziert werden, tun Sie wie folgt "accounts.customer_id". – konung

0

Ein FK (Fremdschlüssel) teilt dem DBMS mit, dass Werte für Unterreihen für eine Spaltenliste an anderer Stelle als Werte für Unterreihen für eine Spaltenliste angezeigt werden müssen. Wann immer das passiert (und es ist nicht bereits durch andere Deklarationen impliziert) deklariere den FK. Wenn Sie zusätzlich möchten, dass eine CASCADE-Aktion bei einer Änderung der referenzierenden Tabelle auf die referenzierte Tabelle angewendet wird, deklarieren Sie dies.

(Es gibt nichts besonderes über CASCADE, dass es nicht für Nicht-FK Situationen angeboten werden können. Es kommt nur mit FKs häufig auf, und es gibt eine explizite Graph von FKs, durch die ihre Wechselwirkungen angemessen zu beschränken.)

Wenn es eine FK cycle gibt, dann müssen Sie Trigger verwenden. Ihre Entscheidung, welche Constraint (s) deklarativ erzwungen werden, sollte & sein, die durch Trigger den Graph der (gewünschten) Constraints berücksichtigen sollte.

Verwandte Themen