dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Home/Hata Teşhis Kütüphanesi/mysql-1215-cannot-add-foreign-key-constraint
MySQL
MySQL 5.7–8.4 LTSVeri Bütünlüğü & Şema
8 dk okuma
ERROR 1215 (HY000): Cannot add foreign key constraint

MySQL Error 1215 — Kısıt Neden Eklenmiyor?

1215 hatasında SHOW ENGINE INNODB STATUS ile gerçek nedeni okuma, tip/charset uyuşmazlığı, indeks ve motor farkları.

İnceleyen:Principal Database Reliability Architect
Test Edilen Sürümler: MySQL 8.4 LTS, 8.0.40 & 5.7.44 (InnoDB / Docker 29.7)

Operasyonel Doğrulama & Güvenilirlik Standardı

Son Teknik İnceleme: 30 Ekim 2026
Test Edilen SürümlerMySQL 8.4 LTS, 8.0.40 & 5.7.44 (InnoDB, Docker 29.7)
Gerekli YetkiALTER TABLE yetkisi; SHOW ENGINE INNODB STATUS için PROCESS yetkisi
Risk Seviyesi
HighFOREIGN_KEY_CHECKS = 0 ile kısıtı zorlamak yetim satırları gizler ve ilk DML işleminde patlamaya yol açar
Beklenen ÇıktıLATEST FOREIGN KEY ERROR analizi sonrası tip, charset, collation ve indeks uyumunun sağlanarak kısıtın eklenmesi
Geri Dönüş (Rollback) Planı:İki kolonun COLUMN_TYPE, CHARACTER_SET ve COLLATION değerlerini birebir eşitleyip ebeveyn kolonda indeks oluşturma
MySQL 8.4 Docs: Foreign Key Requirements & InnoDB Status
İ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 1215 (HY000): Cannot add foreign key constraint

Bu hata, MySQL'in en az açıklama yapan ve mühendisleri en çok çaresiz bırakan hatalarından biridir: Hangi kolonun, hangi kısıtın veya hangi kuralın ihlal edildiğini doğrudan söylemez.

Ancak harika bir haber vardır: InnoDB bu hatanın gerçek nedenini detaylıca günlüğe kaydetmiştir, sadece bunu görebilmek için doğru teşhis komutunu çalıştırmanız gerekir:

sql
SHOW ENGINE INNODB STATUSG

Çıktı içinde şu kritik başlığı arayın:

plaintext
------------------------ LATEST FOREIGN KEY ERROR ------------------------ 2026-10-30 00:45:12 0x7f8 Error in foreign key constraint creation for table `app`.`siparis_detay`: Foreign key constraint 'fk_detay_siparis' cannot be created: referencing column `siparis_id` (bigint unsigned) is not compatible with referenced column `id` (int)

Kısıtın neden reddedildiği bu blokta gün gibi açıktır. 1215 ile karşılaşan herkesin ilk adımı bu bölümü okumaktır.

NOT
MySQL 8.0+ sürümlerinde bu hata bazen daha konuşkan olan `ERROR 3780 (HY000)` olarak fırlatılır: ``plaintext ERROR 3780 (HY000): Referencing column 'siparis_id' and referenced column 'id' in foreign key constraint 'fk_detay_siparis' are incompatible.

▸Nedenini Doğrulayan Teşhis Sorguları

İki kolonun özelliklerini yan yana koyup harf harf karşılaştırın:

sql
SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, CHARACTER_SET_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'app' AND ((TABLE_NAME = 'siparis' AND COLUMN_NAME = 'id') OR (TABLE_NAME = 'siparis_detay' AND COLUMN_NAME = 'siparis_id'));

COLUMN_TYPE, CHARACTER_SET_NAME veya COLLATION_NAME alanlarındaki en küçük bir fark kısıtın reddedilmesi için yeterlidir.


▸Yabancı Anahtar Eklenmesini Engelleyen Yedi Temel Neden

  1. 1İşaretli / İşaretsiz (Signed vs Unsigned) Farkı:

En yaygın nedendir. Ebeveyn tablodaki birincil anahtar BIGINT UNSIGNED iken, çocuk tablodaki yabancı anahtar kolonunu BIGINT (signed) tanımlarsanız MySQL kısıtı kesinlikle reddeder. İkisi de 8 bayttır ancak veri tipleri uyumsuzdur.

  1. 1Karakter Seti (Charset) veya Collation Uyuşmazlığı:

Metin kolonlarında ebeveyn utf8mb4_0900_ai_ci, çocuk ise utf8mb4_general_ci ise kısıt eklenemez.

  1. 1Ebeveyn Kolonda İndeks Eksikliği:

Referans verilen ebeveyn kolon bir B-Tree indeksinin en solundaki (leftmost) kolonu olmak zorundadır. Bileşik bir indeksin (kategori_id, id) ikinci kolonuna referans verilemez.

  1. 1Mevcut Verilerde Yetim Satırlar (Orphaned Rows):

Kısıt sonradan (ALTER TABLE) ekleniyorsa ve çocuk tabloda ebeveynde karşılığı olmayan kayıtlar varsa 1215 alınır. Yetim kayıtları bulun:

sql
SELECT c.id, c.siparis_id FROM app.siparis_detay c LEFT JOIN app.siparis p ON p.id = c.siparis_id WHERE p.id IS NULL LIMIT 10;
  1. 1`ON DELETE SET NULL` + `NOT NULL` Çelişkisi:

Çocuk kolon NOT NULL tanımlanmışken kısıt kuralına ON DELETE SET NULL eklerseniz çelişki nedeniyle 1215 (veya 1830) döner.

  1. 1Depolama Motoru Uyuşmazlığı:

Tablolardan biri MyISAM ise kısıt eklenemez; her iki tablo da InnoDB olmalıdır.

  1. 1Kısıt Adı Çakışması:

MySQL'de kısıt (constraint) adları veritabanı şeması genelinde tekil olmak zorundadır. Başka bir tabloda aynı isimli FK varsa işlem reddedilir.


▸Adım Adım Kalıcı Çözüm

1. Veri Tiplerini ve Collation'ı Birebir Eşitleyin

sql
ALTER TABLE app.siparis_detay MODIFY siparis_id BIGINT UNSIGNED NOT NULL;

2. Kısıtı Düzgün Sözdizimiyle Ekleyin

sql
ALTER TABLE app.siparis_detay ADD CONSTRAINT fk_detay_siparis FOREIGN KEY (siparis_id) REFERENCES app.siparis (id) ON DELETE RESTRICT;
DİKKAT / TEHLİKE
`FOREIGN_KEY_CHECKS = 0` Tuzağı: Kısıt eklenemediğinde internetteki forumlarda sıkça önerilen SET FOREIGN_KEY_CHECKS = 0; komutu veritabanına saatli bomba koymaktır. Bu ayar açıldığında MySQL mevcut yetim kayıtları denetlemeyi atlar ve kısıtı zorla ekler. Ancak veritabanında tutarsız yetim satırlar kalır ve bu kayıtlar ilk DELETE veya UPDATE denemenizde anlaşılması zor hatalarla (H-38) patlar.

▸İlgili Hata Rehberleri & Hub Bağlantıları

Diğer Veritabanı Hata Teşhisleri

Kriz anında başvurabileceğiniz diğer doğrulanmış hata rehberleri.

Tüm Hatalar (50)