Wenn Sie den Namen einer Person als Primärschlüssel verwenden und deren Name geändert wird, müssen Sie den Primärschlüssel ändern. Dies wird ON UPDATE CASCADE
verwendet, da es die Änderung im Wesentlichen auf alle verknüpften Tabellen kaskadiert , die Fremdschlüsselbeziehungen zum Primärschlüssel haben.
Beispielsweise:
USE tempdb;
GO
CREATE TABLE dbo.People
(
PersonKey VARCHAR(200) NOT NULL
CONSTRAINT PK_People
PRIMARY KEY CLUSTERED
, BirthDate DATE NULL
) ON [PRIMARY];
CREATE TABLE dbo.PeopleAKA
(
PersonAKAKey VARCHAR(200) NOT NULL
CONSTRAINT PK_PeopleAKA
PRIMARY KEY CLUSTERED
, PersonKey VARCHAR(200) NOT NULL
CONSTRAINT FK_PeopleAKA_People
FOREIGN KEY REFERENCES dbo.People(PersonKey)
ON UPDATE CASCADE
) ON [PRIMARY];
INSERT INTO dbo.People(PersonKey, BirthDate)
VALUES ('Joe Black', '1776-01-01');
INSERT INTO dbo.PeopleAKA(PersonAKAKey, PersonKey)
VALUES ('Death', 'Joe Black');
A SELECT
gegen beide Tische:
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonKey = pa.PersonKey;
Kehrt zurück:
Wenn wir die PersonKey
Spalte aktualisieren und Folgendes erneut ausführen SELECT
:
UPDATE dbo.People
SET PersonKey = 'Mr Joe Black'
WHERE PersonKey = 'Joe Black';
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonKey = pa.PersonKey;
wir sehen:
Wenn UPDATE
wir den Plan für die obige Anweisung betrachten, sehen wir deutlich, dass beide Tabellen durch eine einzelne Aktualisierungsanweisung aufgrund des Fremdschlüssels aktualisiert werden, der wie folgt definiert ist ON UPDATE CASCADE
:
Klicken Sie auf das Bild, um es deutlicher zu sehen
Zuletzt bereinigen wir unsere temporären Tabellen:
DROP TABLE dbo.PeopleAKA;
DROP TABLE dbo.People;
Die bevorzugte 1 Möglichkeit, dies mit Ersatzschlüsseln zu tun, wäre:
USE tempdb;
GO
CREATE TABLE dbo.People
(
PersonID INT NOT NULL IDENTITY(1,1)
CONSTRAINT PK_People
PRIMARY KEY CLUSTERED
, PersonName VARCHAR(200) NOT NULL
, BirthDate DATE NULL
) ON [PRIMARY];
CREATE TABLE dbo.PeopleAKA
(
PersonAKAID INT NOT NULL IDENTITY(1,1)
CONSTRAINT PK_PeopleAKA
PRIMARY KEY CLUSTERED
, PersonAKAName VARCHAR(200) NOT NULL
, PersonID INT NOT NULL
CONSTRAINT FK_PeopleAKA_People
FOREIGN KEY REFERENCES dbo.People(PersonID)
ON UPDATE CASCADE
) ON [PRIMARY];
INSERT INTO dbo.People(PersonName, BirthDate)
VALUES ('Joe Black', '1776-01-01');
INSERT INTO dbo.PeopleAKA(PersonID, PersonAKAName)
VALUES (1, 'Death');
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonID = pa.PersonID;
UPDATE dbo.People
SET PersonName = 'Mr Joe Black'
WHERE PersonID = 1;
Der Vollständigkeit halber ist der Plan für die Aktualisierungsanweisung sehr einfach und zeigt einen Vorteil gegenüber Ersatzschlüsseln: Im Gegensatz zu jeder Zeile, die den Schlüssel in einem Natural-Key-Szenario enthält , muss nur eine einzige Zeile aktualisiert werden:
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonID = pa.PersonID;
DROP TABLE dbo.PeopleAKA;
DROP TABLE dbo.People;
Die Ausgabe der beiden SELECT
obigen Anweisungen lautet:
Im Wesentlichen ist das Ergebnis in etwa gleich. Ein wesentlicher Unterschied besteht darin, dass der breite natürliche Schlüssel nicht in jeder Tabelle wiederholt wird, in der der Fremdschlüssel vorkommt. In meinem Beispiel verwende ich eine VARCHAR(200)
Spalte, um den Namen der Person zu speichern, was die Verwendung eines VARCHAR(200)
überall erforderlich macht . Wenn viele Zeilen und Tabellen den Fremdschlüssel enthalten, wird viel Speicher verschwendet. Hinweis: Ich spreche nicht davon, dass Speicherplatz verschwendet wird, da die meisten Leute sagen, dass Speicherplatz so billig ist, dass er im Wesentlichen frei ist. Speicher ist jedoch teuer und verdient es, geschätzt zu werden. Wenn Sie eine 4-Byte-Ganzzahl für den Schlüssel verwenden, wird viel Speicherplatz gespart, wenn Sie die durchschnittliche Namenslänge von etwa 15 Zeichen berücksichtigen.
Tangential zu der Frage, wie und warum sich Schlüssel ändern können, ist die Frage, warum natürliche Schlüssel anstelle von Ersatzschlüsseln gewählt werden. Dies ist eine interessante und vielleicht wichtigere Frage, insbesondere, wenn Leistung ein Entwurfsziel ist. Siehe meine Frage dazu hier .
1 - http://weblogs.sqlteam.com/mladenp/archive/2009/10/06/Warum-Ich-präferiere-surrogate-keys-instead-of-natural-keys-in.aspx