dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Home/MySQL/Hata Kodları (Errors)/mysql-1452-foreign-key-constraint
[Teşhis]MySQL MySQL 8.0 - 8.4Intermediate
5 dk okuma

MySQL 1452 Foreign Key Constraint Fails: Neden ve Çözüm

MySQL "Cannot add or update a child row" — Foreign Key Neden Reddediyor?

Yazar / Standart:Kıdemli Veritabanı Mimarı & SRE (dataiotech Labs)
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
İlk 60 Saniye Teşhis Protokolü:

Hata mesajı semptomdur, kök neden değildir. Sunucuyu yeniden başlatmadan veya rastgele ayar değiştirmeden önce aşağıdaki "Nedeni ayırt eden tek sorgu"yu çalıştırarak gerçek senaryoyu netleştirin.

▸Belirti

plaintext
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`app`.`siparis`, CONSTRAINT `fk_siparis_musteri` FOREIGN KEY (`musteri_id`) REFERENCES `musteri` (`id`))

Mesajın kendisi tabloyu, kısıt adını ve kolonu verir — bu yüzden teşhis basittir. Karıştırılan nokta şudur: 1452 ve 1451 iki ayrı hatadır.

  • •1452 → INSERT / UPDATE: Çocuk tabloya, ebeveynde karşılığı olmayan bir değer yazılmak isteniyor.
  • •1451 → DELETE / UPDATE: Ebeveyn silinmek isteniyor ama bağlı çocuk kayıtlar var.

▸Adım adım çözüm

1. Suçlu satırları bulun. Tek tek denemek yerine, ebeveyni olmayan çocuk kayıtları toplu listeleyin:

sql
SELECT c.* FROM siparis c LEFT JOIN musteri p ON p.id = c.musteri_id WHERE c.musteri_id IS NOT NULL AND p.id IS NULL LIMIT 50;

Bu sorgu "ebeveyni olmayan yetim çocuk kayıtlarını" verir. Boş dönüyorsa sorun veri değil, şema uyuşmazlığıdır — 2. adıma geçin.

2. Veri tipi ve karakter setini karşılaştırın. Foreign key, iki kolonun tipinin birebir aynı olmasını gerektirir. INT ile BIGINT, INT UNSIGNED ile INT, utf8mb4 ile latin1 eşleşmez:

sql
SELECT table_name, column_name, column_type, character_set_name, collation_name FROM information_schema.columns WHERE table_schema = DATABASE() AND column_name = 'musteri_id';

MySQL 8.0'da bu tür bir uyuşmazlık ERROR 3780 (HY000): Referencing column ... and referenced column ... are incompatible verir. Çözüm: ALTER TABLE ... MODIFY COLUMN ile tipleri eşitlemektir.

3. Toplu yüklemede sırayı düzeltin. mysqldump çıktısını yüklerken yabancı anahtar kontrolleri yüzünden sıra bozulabilir. Doğru yöntem:

sql
SET FOREIGN_KEY_CHECKS = 0; -- yükleme komutları SET FOREIGN_KEY_CHECKS = 1;
[!WARNING] Bu ayar oturum bazlıdır, yükleme biter bitmez geri açılmalıdır; ve kapatıldığı sürece yetim kayıtlar sessizce oluşur. Yükleme sonrası 1. adımdaki sorguyu mutlaka çalıştırın.

4. Silme hatası (1451) alıyorsanız: İki seçenek var: çocukları önce silmek, ya da şemada kaskad kuralı tanımlamak:

sql
ALTER TABLE siparis ADD CONSTRAINT fk_siparis_musteri FOREIGN KEY (musteri_id) REFERENCES musteri(id) ON DELETE CASCADE;

ON DELETE CASCADE'i bilinçli seçin: bir müşteri silindiğinde tüm sipariş geçmişi kalıcı silinir. Finansal kayıtlarda ON DELETE RESTRICT (varsayılan) daha güvenlidir.


▸Bunu bir daha yaşamamak için

Yabancı anahtar ihlallerini bir uygulama hatası değil, veri bütünlüğü alarmı olarak ele alın: bu hata düzenli olarak görülüyorsa ya bir servis ebeveyn kaydı oluşturmadan çocuk yazıyor, ya da bir yerde FOREIGN_KEY_CHECKS = 0 kalıcı hale gelmiştir.

MySQL Diğer Üretim Rehberleri

Aynı veritabanı motoruna ait doğrulanmış diğer içerikler.

Tümünü Gör