Ich habe eine Tabelle, die Daten enthält, und eine dieser Zeilen muss in einer anderen Tabelle vorhanden sein. Ich möchte also, dass ein Fremdschlüssel die referenzielle Integrität beibehält.
CREATE TABLE table1
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
AnotherID INT NOT NULL,
SomeData VARCHAR(100) NOT NULL
)
CREATE TABLE table2
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
AnotherID INT NOT NULL,
MoreData VARCHAR(30) NOT NULL,
CONSTRAINT fk_table2_table1 FOREIGN KEY (AnotherID) REFERENCES table1 (AnotherID)
)
Wie Sie jedoch sehen können, ist die Spalte in der Tabelle, für die ich einen Fremdschlüssel habe, nicht die PK. Gibt es eine Möglichkeit, diesen Fremdschlüssel zu erstellen, oder eine bessere Möglichkeit, diese referenzielle Integrität aufrechtzuerhalten?
sql
sql-server
Craig
quelle
quelle
table1.ID
?Antworten:
Wenn Sie wirklich einen Fremdschlüssel für einen Nicht-Primärschlüssel erstellen möchten, MUSS es sich um eine Spalte handeln, die eine eindeutige Einschränkung aufweist.
Aus Online-Büchern :
Wenn Sie also in Ihrem Fall
AnotherID
Unikate erstellen, ist dies zulässig. Wenn Sie keine eindeutige Einschränkung anwenden können, haben Sie kein Glück, aber dies ist wirklich sinnvoll, wenn Sie darüber nachdenken.Obwohl, wie bereits erwähnt, wenn Sie einen vollkommen guten Primärschlüssel als Kandidatenschlüssel haben, warum nicht diesen verwenden?
quelle
Wie andere bereits betont haben, wird der Fremdschlüssel im Idealfall als Referenz auf einen Primärschlüssel (normalerweise eine IDENTITY-Spalte) erstellt. Wir leben jedoch nicht in einer idealen Welt, und manchmal kann sogar eine "kleine" Änderung eines Schemas erhebliche Auswirkungen auf die Anwendungslogik haben.
Betrachten Sie den Fall einer Kundentabelle mit einer SSN-Spalte (und einem dummen Primärschlüssel) und einer Anspruchstabelle, die auch eine SSN-Spalte enthält (gefüllt mit Geschäftslogik aus den Kundendaten, aber keine FK vorhanden). Das Design ist fehlerhaft, wird jedoch seit mehreren Jahren verwendet, und drei verschiedene Anwendungen wurden auf dem Schema erstellt. Es sollte offensichtlich sein, dass es ideal wäre, Claim.SSN herauszureißen und eine echte PK-FK-Beziehung aufzubauen, aber auch eine bedeutende Überarbeitung wäre. Auf der anderen Seite kann das Festlegen einer EINZIGARTIGEN Einschränkung für Customer.SSN und das Hinzufügen eines FK für Claim.SSN eine referenzielle Integrität mit geringen oder keinen Auswirkungen auf die Anwendungen gewährleisten.
Versteh mich nicht falsch, ich bin alles für Normalisierung, aber manchmal gewinnt Pragmatismus über Idealismus. Wenn einem mittelmäßigen Design mit einem Pflaster geholfen werden kann, kann eine Operation vermieden werden.
quelle
Nekromantie.
Ich gehe davon aus, dass jemand, der hier landet, einen Fremdschlüssel benötigt, um in einer Tabelle zu spalten, die nicht eindeutige Schlüssel enthält.
Das Problem ist, dass das Datenbankschema denormalisiert wird, wenn Sie dieses Problem haben.
Sie behalten beispielsweise Räume in einer Tabelle mit einem Primärschlüssel für die Raum-UID, einem DateFrom- und einem DateTo-Feld sowie einer anderen UID, hier RM_ApertureID, um denselben Raum zu verfolgen, und einem Soft-Delete-Feld wie RM_Status. Dabei bedeutet 99 "gelöscht" und <> 99 "aktiv".
Wenn Sie also den ersten Raum erstellen, fügen Sie RM_UID und RM_ApertureID als denselben Wert wie RM_UID ein. Wenn Sie dann den Raum auf ein Datum beenden und ihn mit einem neuen Datumsbereich wiederherstellen, ist RM_UID newid (), und die RM_ApertureID aus dem vorherigen Eintrag wird zur neuen RM_ApertureID.
In diesem Fall ist RM_ApertureID ein nicht eindeutiges Feld, sodass Sie keinen Fremdschlüssel in einer anderen Tabelle festlegen können.
Und es gibt keine Möglichkeit, einen Fremdschlüssel auf eine nicht eindeutige Spalte / einen nicht eindeutigen Index zu setzen, z. B. in T_ZO_REM_AP_Raum_Reinigung (WHERE RM_UID ist tatsächlich RM_ApertureID).
Um ungültige Werte zu verhindern, müssen Sie einen Fremdschlüssel festlegen. Andernfalls ist Datenmüll eher früher als später die Folge ...
In diesem Fall können Sie nun (ohne die gesamte Anwendung neu zu schreiben) eine CHECK-Einschränkung einfügen, wobei eine Skalarfunktion das Vorhandensein des Schlüssels überprüft:
quelle
Primärschlüssel müssen immer eindeutig sein, Fremdschlüssel müssen nicht eindeutige Werte zulassen, wenn die Tabelle eine Eins-zu-Viele-Beziehung ist. Es ist vollkommen in Ordnung, einen Fremdschlüssel als Primärschlüssel zu verwenden, wenn die Tabelle durch eine Eins-zu-Eins-Beziehung verbunden ist, nicht durch eine Eins-zu-Viele-Beziehung.
Eine FOREIGN KEY-Einschränkung muss nicht nur mit einer PRIMARY KEY-Einschränkung in einer anderen Tabelle verknüpft sein. Es kann auch definiert werden, um auf die Spalten einer UNIQUE-Einschränkung in einer anderen Tabelle zu verweisen.
quelle