Si estaba usando el nombre de una persona como clave principal y su nombre cambió, necesitaría cambiar la clave primaria. Esto es para lo que ON UPDATE CASCADE
se usa, ya que esencialmente conecta el cambio a todas las tablas relacionadas que tienen relaciones de clave externa con la clave primaria.
Por ejemplo:
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
contra ambas tablas:
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonKey = pa.PersonKey;
Devoluciones:
Si actualizamos la PersonKey
columna y volvemos a ejecutar el 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;
vemos:
Al UPDATE
observar el plan para la declaración anterior , vemos claramente que ambas tablas se actualizan mediante una sola declaración de actualización en virtud de la clave externa definida como ON UPDATE CASCADE
:
haga clic en la imagen de arriba para verla con mayor claridad
Finalmente, limpiaremos nuestras tablas temporales:
DROP TABLE dbo.PeopleAKA;
DROP TABLE dbo.People;
La 1 forma preferida de hacer esto usando claves sustitutas sería:
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, el plan para la declaración de actualización es muy simple y muestra una ventaja para sustituir claves, es decir, solo se necesita actualizar una sola fila en lugar de cada fila que contiene la clave en un escenario de clave natural:
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonID = pa.PersonID;
DROP TABLE dbo.PeopleAKA;
DROP TABLE dbo.People;
Los resultados de las dos SELECT
declaraciones anteriores son:
Esencialmente, el resultado es aproximadamente el mismo. Una diferencia importante es que la clave natural amplia no se repite en todas las tablas donde se produce la clave externa. En mi ejemplo, estoy usando una VARCHAR(200)
columna para contener el nombre de la persona, lo que requiere usar un en VARCHAR(200)
todas partes . Si hay muchas filas y muchas tablas que contienen la clave foránea, eso agregará mucha memoria desperdiciada. Tenga en cuenta que no estoy hablando de que se desperdicie espacio en disco, ya que la mayoría de las personas dicen que el espacio en disco es tan barato como para ser esencialmente libre. La memoria, sin embargo, es costosa y merece ser apreciada. El uso de un entero de 4 bytes para la clave ahorrará una gran cantidad de memoria si considera la longitud promedio del nombre de alrededor de 15 caracteres.
Tangencial a la pregunta sobre cómo y por qué las claves pueden cambiar es la pregunta sobre por qué elegir claves naturales en lugar de claves sustitutas, que es una pregunta interesante y quizás más importante, especialmente cuando el rendimiento es un objetivo de diseño. Vea mi pregunta aquí sobre eso.
1 - http://weblogs.sqlteam.com/mladenp/archive/2009/10/06/Why-I-prefer-surrogate-keys-instead-of-natural-keys-in.aspx