- Konu sahibi
- #1
MySQL foreign key, bir tablodaki sütun veya sütun grubunun aynı ya da başka tablodaki aday anahtara yalnızca geçerli değerlerle bağlanmasını sağlayan kısıtlamadır. Böylece örneğin bir siparişin, veritabanında bulunmayan bir müşteriye bağlanması engellenir. Bağlantı kurulan tabloya üst tablo, bağlantıyı taşıyan tabloya alt tablo denir.
Foreign key veri bütünlüğünü korur; ancak tabloları otomatik olarak birleştirmez veya sorguları kendiliğinden hızlandırmaz. Verileri birlikte okumak için yine
Üst tabloda genellikle
Bu rehber InnoDB için temel ilişkiyi ele alır. Sağlıklı tanımın başlıca koşulları şunlardır:
Aşağıdaki örnek, önce müşteriyi sonra müşteriye bağlı siparişi oluşturur. Tabloların foreign key destekleyen bir depolama motoru kullanması gerekir; bu nedenle
Aynı isimli tabloların bulunmadığı, size ait ayrı deneme veritabanında aşağıdaki örneği uygulayın:
Foreign key tanımlı olduğu halde hata alırsanız önce iki sütunun türünü, tabloların depolama motorunu, referanslanan anahtarın indeksini ve eklediğiniz üst kaydın gerçekten var olup olmadığını karşılaştırın. Kısıtlama veri doğrulama sağlar; yetkilendirme, iş kuralı veya kullanıcıdan gelen veriyi temizleme görevlerini tek başına üstlenmez.
Foreign key veri bütünlüğünü korur; ancak tabloları otomatik olarak birleştirmez veya sorguları kendiliğinden hızlandırmaz. Verileri birlikte okumak için yine
JOIN kullanılır.Nasıl çalışır?
Üst tabloda genellikle
PRIMARY KEY olan id sütunu bulunur. Alt tablodaki customer_id gibi sütun bu değeri referanslar. Alt tabloya eklenen değer üst tabloda yoksa ekleme reddedilir. Üst tablodaki kayıt silinir veya anahtar değeri değiştirilirse, foreign key için tanımlanan davranış uygulanır.Bu rehber InnoDB için temel ilişkiyi ele alır. Sağlıklı tanımın başlıca koşulları şunlardır:
SET NULL kullanacaksanız alt sütun NULL kabul etmelidir. InnoDB’de belirtilmeyen referans davranışı NO ACTION, pratikte RESTRICT’tir. CASCADE ise ayrı bir yaşam döngüsü kararıdır; yabancı anahtar tanımlamak zorunlu silme zinciri kurmak demek değildir.Çalışan temel örnek
Aşağıdaki örnek, önce müşteriyi sonra müşteriye bağlı siparişi oluşturur. Tabloların foreign key destekleyen bir depolama motoru kullanması gerekir; bu nedenle
ENGINE=InnoDB açıkça belirtilmiştir.Aynı isimli tabloların bulunmadığı, size ait ayrı deneme veritabanında aşağıdaki örneği uygulayın:
Kod:
CREATE TABLE fk_demo_customers (
id INT NOT NULL,
name VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;
CREATE TABLE fk_demo_orders (
id INT NOT NULL,
customer_id INT NOT NULL,
order_total DECIMAL(10,2) NOT NULL,
PRIMARY KEY (id),
CONSTRAINT fk_orders_customer
FOREIGN KEY (customer_id)
REFERENCES fk_demo_customers (id)
ON DELETE RESTRICT
ON UPDATE CASCADE
) ENGINE=InnoDB;
INSERT INTO fk_demo_customers (id, name)
VALUES (1, 'Ayşe');
INSERT INTO fk_demo_orders (id, customer_id, order_total)
VALUES (1001, 1, 250.00);
SELECT o.id, c.name, o.order_total
FROM fk_demo_orders AS o
JOIN fk_demo_customers AS c ON c.id = o.customer_id;
- Sorgunun sonunda
1001,Ayşeve250.00değerlerini görmeniz başarılı bağlantıyı gösterir.fk_demo_customerstablosundaid=1bulunmasaydı sonINSERTreddedilirdi; bu, kısıtlamanın çalıştığını gösterir. -
DELETE FROM fk_demo_customers WHERE id = 1;komutunu denerseniz sipariş bağlı olduğu için silme reddedilir. Siparişin de silinmesini istiyorsanızON DELETE CASCADEseçimini bilinçli olarak kullanarak foreign key'i yeniden oluşturmanız gerekir.
| Kontrol | Gereken uyum | Neden? |
|---|---|---|
| Üst anahtar | Primary key veya uygun unique key | Hedef kaydı belirlemek |
| Sütunlar | Uyumlu tür ve sayısal işaret; metinde charset/collation | Geçersiz eşleştirmeyi önlemek |
| Motor | İki tabloda aynı ve FK destekli motor | Kısıtlamanın uygulanması |
| Mevcut veriler | Alt değer için üst kayıt bulunması | Yetim kayıtları engellemek |
Tanımlarken kontrol edilecek noktalar
- Referans verilen sütun üst tabloda
PRIMARY KEYveya uygun bir benzersiz anahtar olmalıdır. - İki sütunun veri tipi ve işaretsiz işaretli durumu uyumlu olmalıdır. Örneğin
INTileINT UNSIGNEDeşleştirmesi sorun çıkarabilir. - Üst tabloyu oluşturmadan alt tablonun foreign key'ini tanımlamayın; önce referanslanan tabloyu hazırlayın.
- Mevcut tablolara sonradan kısıtlama ekliyorsanız, alt tabloda karşılığı olmayan değerleri önce temizleyin veya düzeltin.
-
CASCADEseçimini kolaylık olsun diye değil, alt kayıtların gerçekten üst kayda bağımlı olduğu durumda kullanın. Aksi halde tek bir silme beklenenden fazla kaydı kaldırabilir.
Foreign key tanımlı olduğu halde hata alırsanız önce iki sütunun türünü, tabloların depolama motorunu, referanslanan anahtarın indeksini ve eklediğiniz üst kaydın gerçekten var olup olmadığını karşılaştırın. Kısıtlama veri doğrulama sağlar; yetkilendirme, iş kuralı veya kullanıcıdan gelen veriyi temizleme görevlerini tek başına üstlenmez.