Mehmet

WFN Üye
Konular
1,851
Mesajlar
1,852
Çözüm
0
Ticaret Puanı
0
Üyelik
1 Ay 6 Gün
Konum
YurtDışı
Web Sitesi
Var
Alanı
Google Adsense
1/1
Konu sahibi
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 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;

  1. Sorgunun sonunda 1001, Ayşe ve 250.00 değerlerini görmeniz başarılı bağlantıyı gösterir. fk_demo_customers tablosunda id=1 bulunmasaydı son INSERT reddedilirdi; bu, kısıtlamanın çalıştığını gösterir.
  2. DELETE FROM fk_demo_customers WHERE id = 1; komutunu denerseniz sipariş bağlı olduğu için silme reddedilir. Siparişin de silinmesini istiyorsanız ON DELETE CASCADE seçimini bilinçli olarak kullanarak foreign key'i yeniden oluşturmanız gerekir.

KontrolGereken uyumNeden?
Üst anahtarPrimary key veya uygun unique keyHedef kaydı belirlemek
SütunlarUyumlu tür ve sayısal işaret; metinde charset/collationGeçersiz eşleştirmeyi önlemek
Motorİki tabloda aynı ve FK destekli motorKısıtlamanın uygulanması
Mevcut verilerAlt değer için üst kayıt bulunmasıYetim kayıtları engellemek


Tanımlarken kontrol edilecek noktalar​


  1. Referans verilen sütun üst tabloda PRIMARY KEY veya uygun bir benzersiz anahtar olmalıdır.
  2. İki sütunun veri tipi ve işaretsiz işaretli durumu uyumlu olmalıdır. Örneğin INT ile INT UNSIGNED eşleştirmesi sorun çıkarabilir.
  3. Üst tabloyu oluşturmadan alt tablonun foreign key'ini tanımlamayın; önce referanslanan tabloyu hazırlayın.
  4. Mevcut tablolara sonradan kısıtlama ekliyorsanız, alt tabloda karşılığı olmayan değerleri önce temizleyin veya düzeltin.
  5. CASCADE seç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.

Sık sorulan sorular​

Foreign key sütunu NULL olabilir mi?​

Evet. Sütun NULL kabul ediyorsa bağlantı isteğe bağlı olabilir. NULL üst tabloda aranacak normal anahtar değeri gibi değerlendirilmez. Sıfır veya boş metin ise NULL değildir; bunları kullanacaksanız gerçekten karşılık gelen geçerli anahtarın bulunması gerekir.

foreign_key_checks yeniden açılınca eski veriler taranır mı?​

Hayır. Kontrol kapalıyken eklenmiş kayıtların tamamı yeniden açıldığında kendiliğinden doğrulanmaz. İçe aktarma veya bakım sonrası mevcut verinin tutarlılığını ayrıca denetleyin. Hata mesajını susturmak için kontrolü kapatmak, yanlış ilişkiyi düzeltmez ve yetim kayıt bırakabilir.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Konuyu görüntüleyenler

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic