Se você estivesse usando o nome de uma pessoa como chave primária e o nome dela fosse alterado, seria necessário alterar a chave primária. Isto é o que ON UPDATE CASCADE
é usado para uma vez que essencialmente cascatas a descer mudança a todas as tabelas relacionadas que têm relações-chave estrangeira para a chave primária.
Por exemplo:
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
em ambas as tabelas:
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonKey = pa.PersonKey;
Devoluções:
Se atualizarmos a PersonKey
coluna e executar novamente o 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;
Nós vemos:
Observando o plano da UPDATE
instrução acima , vemos claramente que ambas as tabelas são atualizadas por uma única instrução de atualização em virtude da chave estrangeira definida como ON UPDATE CASCADE
:
clique na imagem acima para vê-la com mais clareza
Por fim, limparemos nossas tabelas temporárias:
DROP TABLE dbo.PeopleAKA;
DROP TABLE dbo.People;
O preferido 1 maneira de fazer isso usando chaves substitutas seria:
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;
Para completar, o plano da instrução de atualização é muito simples e mostra uma vantagem em substituir as chaves, ou seja, apenas uma única linha precisa ser atualizada em oposição a todas as linhas que contêm a chave em um cenário de chave natural:
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonID = pa.PersonID;
DROP TABLE dbo.PeopleAKA;
DROP TABLE dbo.People;
A saída das duas SELECT
instruções acima são:
Essencialmente, o resultado é aproximadamente o mesmo. Uma grande diferença é que a chave natural ampla não é repetida em todas as tabelas em que a chave estrangeira ocorre. No meu exemplo, estou usando uma VARCHAR(200)
coluna para conter o nome da pessoa, o que exige o uso de um em VARCHAR(200)
qualquer lugar . Se houver muitas linhas e muitas tabelas contendo a chave estrangeira, isso adicionará muita memória desperdiçada. Observe que não estou falando de desperdício de espaço em disco, já que a maioria das pessoas diz que o espaço em disco é tão barato que é essencialmente gratuito. A memória, no entanto, é cara e merece ser valorizada. O uso de um número inteiro de 4 bytes para a chave economizará uma grande quantidade de memória quando você considerar o tamanho médio do nome em torno de 15 caracteres.
Importante para a pergunta sobre como e por que as chaves podem mudar é a pergunta sobre por que escolher chaves naturais em vez de chaves substitutas, que é uma pergunta interessante e talvez mais importante, especialmente onde o desempenho é um objetivo do projeto. Veja minha pergunta aqui sobre isso.
1 - http://weblogs.sqlteam.com/mladenp/archive/2009/10/06/Why-I-prefer-surrogate-keys-instead-of-natural-keys-in.aspx