MySQL Foreign Key (Dış Anahtar) Kontrolü

Bildiğiniz gibi MySQL, ilişkisel bir veritabanı yönetim sistemi(RDBMS). Bu da demek oluyor ki doğru tablo motoru kullanıldığında tablolar arasında ilişkilendirmeler yapabiliyoruz.

Bu yazımda ilişkilendirilmiş tablolarda düzenleme yapılması sonrasında alınacak aksiyonlara değineceğim. Öncelikle InnoDB yada diğer ilişkisel tablo motorlarından birini kullanmamız gerekiyor. MyISAM ne yazık ki bu desteğe sahip değil.

Bu konuyu en iyi anlamak ve anlatmak için örnek bir senaryo üzerinden gitmenin daha iyi olacağını düşündüm. İnternette çok sık karşımıza çıkan bir yapı var ve ben bunu en temel haliyle ele almak istiyorum. Konu: üyenin sitenizden bir ürün satın alması, yani e-ticaret.

Diyelim ki 3 adet tablomuz var. Bunlar; üye, ürün ve sipariş tabloları olsun. Şöyle bir düşündüğümüzde üye ve ürün birbirinden aslen bağımsızdır. Ancak sipariş tablosunda hem ürünün hem de üyenin bilgileri olmalı ki, kimin ne sipariş verdiğini bilelim. Yani sipariş tablosu hem ürün hem de üye tablosu ile ilişkili olmalı.

Mysql Foreign Key Örnek

Örnek Tablo

Yukarıda gördüğünüz gibi, üye bir ürün sipariş ettiğinde, sipariş tablosuna hem üyenin bilgileri hem de ürünün bilgileri kaydediliyor. Dikkat ederseniz üye için sadece uye_id ve ürün için urun_id bize yeterliyken, ben urun_ad, fiyat, uye_adsoyad gibi alanları da ekledim.

Bunun sebebini şöyle açıklayayım; diyelim ki ileride aynı ürünü satmak istemiyorsunuz, dolayısıyla veritabanından sildiniz. Bu da yetmedi birde üyeniz gelip, üyeliğini silme başvurusunda bulundu ve onu da veritabanından sildiniz. Ardından siparişleri listelemek ve id alanlarına göre ürünü yada üyeyi görmek isterseniz sistem ilişkili olduğu verileri bulamadığı için hata verecektir.

Dolayısıyla diğer eklenen alanlarda sipariş anında ürün ve üye bilgilerini de buraya kayıt edersek bu sorunu da bertaraf etmiş oluyoruz.

(Siz her iki tabloya da durum alanı ekleyip bunları pasif ederek tablo haricinde görünmemesini sağlayabilirsiniz ama örneği basitleştirmek için biraz kırpmam gerekti :))

Tam da bu senaryodan yola çıkarak, foreign key(dış anahtar)’ın ne aşamada işe yaradığına bakalım. Aşağıda örnek veritabanımızın kodları da mevcut.

SİLME DURUMU:

ON DELETE RESTRICT: eğer üye yada ürün silinmeye çalışılırsa izin vermez. Öncelikle sipariş tablosundan ilgili satırın silinmesi gerekir.

ON DELETE CASCADE: üye yada ürün silinmesi durumunda sipariş tablosundan ilgili satırları da siler.

ON DELETE SET NULL: sipariş tablosundaki ilgili alanı NULL olarak değiştirir (ki biz de bunu istiyoruz bu örnekte)

ON DELETE NO ACTION: RESTRICT ile aynı şekilde çalışır.

 

GÜNCELLEME DURUMU:

ON UPDATE RESTRICT: eğer üye tablosundaki ilişkili alan(uye_id) yada ürün tablosundaki ilişkili alan(urun_id) güncellenmeye çalışılırsa izin vermez.

ON UPDATE CASCADE: üye yada ürün tablosundaki ilgili alanın güncellenmesi durumunda sipariş tablosundaki ilgili(uye_id ve urun_id) satırları da günceller (biz de bunu istiyoruz).

ON UPDATE SET NULL: sipariş tablosundaki ilgili alanı NULL olarak değiştirir

ON UPDATE NO ACTION: RESTRICT ile aynı şekilde çalışır.

 

SONUÇ

Evet aslında yeterince basit bir fonksiyon ancak bunları yazılım tarafında yapmaktansa veritabanı tasarımı esnasında ayarlamak daha iyi olacaktır. Yazılımda bu gibi durumlar ve yetim veri dediğimiz kayıtları farketmek ve düzenlemek daha zor oluyor. Ayrıca işin tabi bir de performans tarafı var.

Ben mümkün olduğunca MySQL’de InnoDB tablo motoru kullanılması taraftarıyım. Bana göre MyISAM’ın tek üstünlüğü aramalarda full text search bulunmasıydı. Ancak MySQL’in 5.6 sürümüyle birlikte artık bu özellikte mevcut duruma geldi. Ki daha alt sürüm olsa bile bunu sphinx yada benzeri arama motorları ile daha efektif bir biçimde çözebilmekteyiz.

Gerçek hayat örneği için biraz fazla basite indirgenmiş bir senaryo olduğunun farkındayım. Amacım sadece konuyu açıklayabilmek olduğu için daha fazla tablo/alan eklemedim. Umarım yardımcı olabilmişimdir. Sağlıcakla kalın.

Bir Cevap Yazın