Se stavi usando il nome di una persona come chiave primaria e il suo nome fosse cambiato, dovrai cambiare la chiave primaria. Questo è ciò per cui ON UPDATE CASCADE
viene utilizzato poiché essenzialmente riduce a cascata la modifica a tutte le tabelle correlate che hanno relazioni chiave esterna con la chiave primaria.
Per esempio:
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
contro entrambi i tavoli:
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonKey = pa.PersonKey;
Ritorna:
Se aggiorniamo la PersonKey
colonna ed eseguiamo nuovamente 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;
vediamo:
Guardando il piano per l' UPDATE
istruzione precedente , vediamo chiaramente che entrambe le tabelle sono aggiornate da una singola istruzione di aggiornamento in virtù della chiave esterna definita come ON UPDATE CASCADE
:
fai clic sull'immagine qui sopra per vederla in maggiore chiarezza
Infine, ripuliremo le nostre tabelle temporanee:
DROP TABLE dbo.PeopleAKA;
DROP TABLE dbo.People;
Il modo 1 preferito per farlo usando le chiavi surrogate sarebbe:
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;
Per completezza, il piano per l'istruzione update è molto semplice e mostra un vantaggio nel surrogare le chiavi, vale a dire che è necessario aggiornare solo una singola riga rispetto a ogni riga contenente la chiave in uno scenario a chiave naturale:
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonID = pa.PersonID;
DROP TABLE dbo.PeopleAKA;
DROP TABLE dbo.People;
L'output delle due SELECT
dichiarazioni precedenti sono:
In sostanza, il risultato è approssimativamente lo stesso. Una grande differenza è che l'ampia chiave naturale non viene ripetuta in ogni tabella in cui si verifica la chiave esterna. Nel mio esempio, sto usando una VARCHAR(200)
colonna per contenere il nome della persona, che richiede l'uso di VARCHAR(200)
ovunque . Se ci sono molte righe e molte tabelle contenenti la chiave esterna, ciò aggiungerà molta memoria sprecata. Nota, non sto parlando di spreco di spazio su disco poiché la maggior parte delle persone afferma che lo spazio su disco è così economico da essere essenzialmente libero. La memoria, tuttavia, è costosa e merita di essere apprezzata. L'uso di un numero intero a 4 byte per la chiave consente di risparmiare una grande quantità di memoria se si considera la lunghezza media del nome di circa 15 caratteri.
Tangenziale alla domanda su come e perché le chiavi possono cambiare è la domanda sul perché scegliere chiavi naturali piuttosto che chiavi surrogate, che è una domanda interessante e forse più importante, specialmente dove le prestazioni sono un obiettivo di progettazione. Vedi la mia domanda qui a riguardo.
1 - http://weblogs.sqlteam.com/mladenp/archive/2009/10/06/Why-I-prefer-surrogate-keys-instead-of-natural-keys-in.aspx