“ON UPDATE CASCADE” ne zaman kullanılır?


420

"ON DELCE CASCADE" i düzenli olarak kullanıyorum, ancak "ON UPDATE CASCADE" i asla kullanmam, çünkü hangi durumda yararlı olacağından emin değilim.

Tartışma uğruna bazı kodları görelim.

CREATE TABLE parent (
    id INT NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (id)
);

CREATE TABLE child (
    id INT NOT NULL AUTO_INCREMENT, parent_id INT,
    INDEX par_ind (parent_id),
    FOREIGN KEY (parent_id)
        REFERENCES parent(id)
        ON DELETE CASCADE
);

"ON CASCADE ON" için, bir ebeveyni olan bir ebeveyn idsilinirse, alt öğedeki bir kayıt parent_id = parent.idotomatik olarak silinir. Bu hiç sorun değil.

  1. Bu id, ebeveyn güncellendiğinde "ON UPDATE CASCADE" öğesinin aynı şeyi yapacağı anlamına mı geliyor?

  2. (1) doğruysa, parent.idgüncellenebilir değilse (veya asla güncellenmeyecekse) olduğu gibi AUTO_INCREMENTveya her zaman ayarlı olduğu gibi "ON UPDATE CASCADE" kullanmaya gerek yoktur TIMESTAMP. Bu doğru mu?

  3. (2) doğru değilse, başka hangi durumlarda "GÜNCELLEME KASKASINDA" kullanmalıyız?

  4. Ya (bazı nedenlerden dolayı) child.parent_idmevcut olmayan bir şey olarak güncellersem, o zaman otomatik olarak silinir mi?

Eh, biliyorum, yukarıdaki sorunun bazıları programlı olarak anlamak için test olabilir, ancak bunların herhangi birinin veritabanı satıcısına bağlı olup olmadığını da bilmek istiyorum.

Lütfen biraz ışık tut.


Yanıtlar:


468

Birincil anahtarınız yalnızca otomatik olarak artırılan bir kimlik değeri ise, ON UPDATE CASCADE için gerçek bir kullanımınız olmayacağı doğrudur.

Ancak, birincil anahtarınızın 10 basamaklı bir UPC barkodu olduğunu ve genişleme nedeniyle, 13 basamaklı bir UPC barkoduna değiştirmeniz gerektiğini varsayalım. Bu durumda, ON UPDATE CASCADE, birincil anahtar değerini değiştirmenize izin verir ve değere yabancı anahtar başvuruları olan tüm tablolar buna göre değiştirilir.

# 4'e referansla, alt kimliğini üst tabloda bulunmayan bir şeyle değiştirirseniz (ve referans bütünlüğünüz varsa), yabancı anahtar hatası almanız gerekir.


6
ON UPDATE CASCADEOtomatik artan bir anahtar kullanmayan eski bir tablodaki birincil anahtarları güncellemek için kendimi kullanmak zorunda kaldım
BlueRaja - Danny Pflughoeft

86
  1. Evet, bu, örneğin UPDATE parent SET id = 20 WHERE id = 1010 numaralı tüm parent_id'leri de yaparsanız 20'ye güncellenecek demektir.

  2. Yabancı anahtarın başvurduğu alanı güncellemezseniz, bu ayara gerek yoktur

  3. Başka bir kullanım düşünemiyorum.

  4. Yabancı anahtar kısıtlaması başarısız olacağından bunu yapamazsınız.


29

Bence hemen hemen çivilenmişsin!

Veritabanı tasarımı en iyi uygulamalarını takip ederseniz ve birincil anahtarınız asla güncellenemezse (ki her zaman yine de böyle olması gerekir), o zaman gerçekten ON UPDATE CASCADEmaddeye ihtiyacınız yoktur .

Zed , birincil anahtarınız olarak doğal bir anahtar (örneğin, veritabanı tablonuzdan normal bir alan) kullanırsanız, birincil anahtarlarınızı güncellemeniz gereken belirli durumlar olabileceğini iyi bir noktaya işaret etti . Son zamanlardaki diğer bir örnek, çok uzun zaman önce 10'dan 13 basamağa + karaktere değişen ISBN (Uluslararası Standart Kitap Numaraları) olacaktır.

Birincil anahtarınız olarak yedek anahtarlar (örneğin yapay olarak sistem tarafından oluşturulan) kullanmayı seçerseniz (en nadir durumlar dışında tercih edilen seçim bu olur) durum böyle değildir.

Sonuçta: birincil anahtarınız asla değişmezse, hiçbir zaman ON UPDATE CASCADEyan tümceye ihtiyacınız olmaz .

üzüm posası


"Yapay olarak sistem tarafından üretilen" anahtarlar nedir? Uuıdlerin?
HPWD

1
@HPWD: Sadece bir "yapay" anahtar sistemi tarafından üretilir (dayalı veya gerçek verilerden türetilen olmayan bir değer) - bu olabilir gerçekten ya da bir şey - - bir GUID veya bir INT ya da bir BIGINT doesn önemli değil. Önemli olan: bu değer hiçbir şekilde gerçek verilerinizle ilgili değildir ve sistem bu değeri sizin için otomatik olarak üretir.
marc_s

@ marc-s Bunu yazmak için zaman ayırdığınız için teşekkür ederiz. Cevabınız mükemmel.
HPWD

2
Doğal anahtarlara sahip tek sütunlu bir tablo, bence enumlara (en azından MySQL DB tatlarında) iyi ve temiz bir alternatiftir. Örneğin, bir tablo dikkate colorssatır ile blue, purple, yellowve bir masa products, bir ile product_coloriçin FK'ed olmak sütun colorstablo. Bu, bir enum gibi seçenekleri kısıtlar, ancak otomatik artan bir tamsayıdan farklı olarak, renk adını almak için bir birleştirmeye gerek yoktur. Böyle bir durumda, bunun yerine çağrılması gerektiğine on update cascadekarar verirseniz iyi bir fikirdir . purpleviolet
okdewit

18

Birkaç gün önce tetikleyicilerle ilgili bir sorunum vardı ve ON UPDATE CASCADEbunun yararlı olabileceğini anladım . Bu örneğe bir göz atın (PostgreSQL):

CREATE TABLE club
(
    key SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);

CREATE TABLE band
(
    key SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);

CREATE TABLE concert
(
    key SERIAL PRIMARY KEY,
    club_name TEXT REFERENCES club(name) ON UPDATE CASCADE,
    band_name TEXT REFERENCES band(name) ON UPDATE CASCADE,
    concert_date DATE
);

Benim durumumda, konser tablosunu güncellemek için bazı ek işlemler (tetikleyici) tanımlamak zorunda kaldım. Bu işlemler kulüp_adı ve grup_adı'nı değiştirmek zorunda kaldı. Referans nedeniyle yapamadım. Konseri değiştiremedim ve sonra kulüp ve grup masalarıyla uğraşamadım. Bunu başka şekilde de yapamadım. ON UPDATE CASCADEsorunu çözmenin anahtarıydı.


3
İyi yorum. Güncelleme kaskadında da yararlı buluyorum, her durumda kimliğinizi değiştirmeniz gerekiyor. Ayrıca bu değişikliğin çok tipik olmaması gerektiğine dair başkalarına da katılıyorum. Örneğin, alıntı yapmanız durumunda, büyük miktarlarda veri, belki de metin alanlarını kullanarak yabancı anahtarlarla ilişkilendirmenin veritabanı motorunun en hızlı performansıyla sonuçlanamayabileceğini düşünüyorum. Konser tablosundaki yabancı ilişkinin club.SERIAL ve band.SERIAL kullanması durumunda, addaki değişikliklerin tablolar arasındaki ilişkiyi etkilemeyeceğini gözlemleyin. Ancak, ONDATE CASCADE'in acil durumları çözmek için harika bir araç olduğunu düşünüyorum. Saygılarımızla
David L

4
Bu oldukça tartışmalı bir örnek oluşturan tartışmalı bir tasarımdır. Her tablonun birincil anahtarı yerine s'ye başvurursanız, iki SERIALsütunu birincil anahtar olarak clubve bandbirincil anahtar olarak tutmanın anlamı nedir name?
sm

Kısacası, bu alanı başka bir tablodan çoğalıyorsanız ve güncel olması gerektiğinde kullanışlıdır.
Kamil Tomšík

4

Yorumum esas olarak 3. noktaya atıfta bulunuyor: üst anahtarın güncellenebilir olmadığını varsayarsak, ON UPCATE CASCADE hangi koşullar altında uygulanabilir? İşte bir dava.

Birden fazla uydu veritabanının bir master ile birleştirilmesi gereken bir çoğaltma senaryosuyla ilgileniyorum. Her uydu aynı tablolarda veri üretir, bu nedenle tabloların ana ile birleştirilmesi, benzersizlik kısıtlamasının ihlaline yol açar. ON UPDATE CASCADE'i her birleştirme sırasında anahtarları yeniden artırdığım bir çözümün parçası olarak kullanmaya çalışıyorum. GÜNCELLEŞTİRİLMİŞ CASCADE, sürecin bir kısmını otomatikleştirerek bu işlemi basitleştirmelidir.


3

Bu mükemmel bir soru, dün aynı soruyu sordum. Ben "ON UPDATE CASCADE" gibi bir şey varsa, özellikle ARANAN bu sorun hakkında düşündüm ve Neyse ki SQL tasarımcıları da bunu düşünmüştü. Ted.strauss'a katılıyorum ve Noran'ın davasını da yorumladım.

Ne zaman kullandım? Ted'in belirttiği gibi, bir kerede birkaç veritabanını tedavi ettiğinizde ve bunlardan birinde yapılan değişikliklerin tek bir tabloda, Ted'in "uydu veritabanı" olarak adlandırdığı şeyde herhangi bir üreme vardır, ID ve herhangi bir nedenle yeni bir veri oluşturmanız gerekir, eski verilerdeki verileri güncelleyemiyorsanız (örneğin izinler nedeniyle veya çok geçici bir durumda haslık arıyorsanız) normalleşmenin tüm kurallarına mutlak ve mutlak saygıyı hak etmiyor, çünkü çok kısa ömürlü bir fayda olacak)

İki noktada hemfikirim:

(A.) Evet, çoğu zaman daha iyi bir tasarım bunu önleyebilir; FAKAT

(B.) Taşıma, veritabanı çoğaltma veya acil durumları çözme durumlarında, var olup olmadığını araştırmaya gittiğimde neyse ki orada olan BÜYÜK BİR ARAÇ.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.