Bir kişinin adını birincil anahtar olarak kullanıyorsanız ve adı değiştiyse, birincil anahtarı değiştirmeniz gerekir. ON UPDATE CASCADE
Temel anahtarla yabancı anahtar ilişkileri olan tüm ilgili tablolara geçişi esas aldığı için kullanılan budur .
Örneğin:
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');
Her SELECT
iki tabloya karşı A :
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonKey = pa.PersonKey;
İadeler:
PersonKey
Sütunu güncellersek ve yeniden çalıştırırsak 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;
görürüz:
Yukarıdaki UPDATE
ifadenin planına baktığımızda, her iki tablonun, aşağıdaki gibi tanımlanan yabancı anahtar sayesinde tek bir güncelleme ifadesiyle güncellendiğini açıkça görüyoruz ON UPDATE CASCADE
:
daha net görmek için yukarıdaki resme tıklayın
Son olarak, geçici tablolarımızı temizleyeceğiz:
DROP TABLE dbo.PeopleAKA;
DROP TABLE dbo.People;
Yedek anahtarlar kullanarak bunu yapmanın tercih edilen 1 yolu:
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;
Tamlık için, güncelleme ifadesi planı çok basittir ve anahtarları taşımak için bir avantaj gösterir, yani doğal anahtar senaryosunda anahtarı içeren her satırın aksine yalnızca tek bir satırın güncellenmesi gerekir :
SELECT *
FROM dbo.People p
INNER JOIN dbo.PeopleAKA pa ON p.PersonID = pa.PersonID;
DROP TABLE dbo.PeopleAKA;
DROP TABLE dbo.People;
SELECT
Yukarıdaki iki ifadeden elde edilen çıktı :
Esasen, sonuç yaklaşık olarak aynıdır. Önemli bir fark, geniş doğal anahtarın yabancı anahtarın oluştuğu her tabloda tekrarlanmamasıdır. VARCHAR(200)
Örneğimde, kişinin adını tutmak için VARCHAR(200)
her yerde kullanılmasını gerektiren bir sütun kullanıyorum . Çok sayıda satır ve yabancı anahtarı içeren çok sayıda tablo varsa, bu çok fazla boşa bellek katar. Not, çoğu insan disk alanının aslında ücretsiz olacak kadar ucuz olduğunu söyledi çünkü boşa harcanan disk hakkında konuşmuyorum. Bununla birlikte, bellek pahalıdır ve sevilmeyi hak eder. Anahtar için 4 baytlık bir tamsayı kullanmak, yaklaşık 15 karakterlik ortalama ad uzunluğunu düşündüğünüzde büyük miktarda bellek tasarrufu sağlayacaktır.
Anahtarların nasıl ve neden değişebileceği sorusuna teğet , yedek anahtarlar üzerinde doğal anahtarların neden seçilmesiyle ilgili soru, bu da özellikle performansın bir tasarım hedefi olduğu ilginç ve belki de daha önemli bir sorudur. Benim soruya bakın burada bu konuda.
1 - http://weblogs.sqlteam.com/mladenp/archive/2009/10/06/Why-I-prefer-surrogate-keys-instead-of-natural-keys-in.aspx