Merhabalar.

Bu yazıda veri tabanı normalizasyonunun ne olduğundan ve normalizasyon yapılmadığında gerçekleşen anomaly tiplerini anlatacağım.

Database Normalization Nedir?

Veri tabanlarında verilerin çoklanmasını, tekrarlanmasını minimize etmek amacıyla verilerin birden fazla tabloya dağıtılmasında kullanılan tekniğe Database Normalization denmektedir.

Verilen Çoklanması, Tekrarlanması İle Kastedilen Nedir?

Şimdi alttaki resimdeki bir tablonuz ve saklanan verileriniz olduğunu düşünün.

Burada göreceğimiz üzere karakterlerin ait oldukları dizinin adı, kanalı ve yayınlanma tarihleri her kayıt için sürekli tekrar ediyor. İşte buna Data Redundancy adı veriliyor. Kayıtlar gereksiz yere veritabanını şişirecek şekilde yazılıyorlar.

Bu durum şunlara da sebep olur:

  • Ekleme Problemleri (Insertion Anomally): Yeni bir karakter eklemek istediğiniz zaman kanal adı, dizi adı ve yayınlanma tarihlerini hep tam olarak girmek zorundasınız. Birini yanlış girdiğinizde örneğin görüntüleme vs. sorunları çıkabilir. Ya da sisteme bu dizin için 50 karakter eklemeniz gerekiyor diye düşünelim. O zaman 50 kere aynı datayı sisteme girmek gerekecek.
  • Silme Problemleri (Deletion Anomally): Şimdi bu tablodaki kayıtların hepsini sildiğimiz düşünelim. Biz kayıtları sildiğimizde karakterlerin yanında diziye ait bilgiler de siliniyor. Son kayıt da silindiği anda artık dizinin ismi, kanal bilgisi ve yayınlanma yılları da silinmiş olacak.
  • Güncelleme Problemleri (Updation Anomally): Diyelim ki kanalım adı NBC’den başka bir şeye çevrildi ve sizin de sistemde bunu değiştirmeniz gerekiyor. Burada da kanal ismi NBC olan bütün kayıtlar üzerinde update script’i çalıştırmanız gerekecek. Herhangi bir şekilde kayıtlardan bir ya da birkaçı için bu güncelleme çalıştırılamazsa o zaman da tutarsız veri problemi ortaya çıkar.

Çözüm

Burada yapılacak işi elimizdeki tabloyu karakterler ve diziler şeklinde 2 tabloya bölmek olacaktır. Öncelikle elimizdeki diziye ait bilgiler ile şu şekilde tablo oluşturup kayıt girebiliriz:

Ardından karakterler tablosunu da şu şekilde düzenleyebiliriz:

Gördüğünüz gibi data tekrarını minimize ettik ve bahsi geçen 3 problem için de çözüm sağladık.

  • Ekleme sırasında sadece dizinin id bilgisini vermek ekleme problemini
  • Tüm karakter kayıtları silinse bile dizi etkilenmeyeceği için silme problemini
  • Diziye ait bir değişiklik olduğunda tek kayıt değişeceği için güncelleme problemini çözmüş olduk.

Database Normalization dediğimiz kavram birkaç farklı tipte gerçeklenebiliyor. Biz bu yazıda aşağıdaki 3 tipi ele alacağız:

  1. 1st Normal Form
  2. 2nd Normal Form
  3. 3rd Normal Form

1st Normal Form

Database Normalization çerçevesinde bir veritabanının en azından uygulaması gereken normalization tipi olarak geçmektedir 1st Normal Form. Bu normalization tipi 4 adet kural üzerine kuruludur.

  1. Her bir kolon tek değer içermeli. Eğer bir kolon A,B şeklinde değer içeriyorsa bu kuralı bozuyor demektir. Örneğin Saul Goodman’ın oynadığı diziler için bir kolonda “Breaking Bad, Better Call Saul” şeklinde veri varsa bu kural ihlal edilmiş olur.
  2. Bir kolon her zaman aynı tipte veri tutmalıdır ve başka kolondaki veri tipi ile karıştırılmamalıdır. Örneğin 5 kayıt içeren bir tabloda bir kolon için 4 kayıt tarih bilgisi içerirken 1 kayıt başka tipte bir bilgi tutarsa bu kural ihlal edilmiş olur.
  3. Bir tablodaki her kolon eşsiz isme sahip olmalı. Yani 2 kolonda aynı isim olmamalı. Buna zaten modern DBMS yazılımları izin vermiyor :)
  4. Veritabanına kayıt sıraları bizim için sorun teşkil etmemeli. Örneğin ID kolonu 1,3,5,2,4 şeklinde sıralanıyorsa bu bizim için sorun olmamalı. Biz zaten SQL’de order by komutu ile bunları istediğimiz sırada çekebiliriz.

2nd Normal Form

2nd Normal Form için 2 adet şart bulunmaktadır.

  1. 1st Normal Form’daki tüm kurallar sağlanmış olmalı.
  2. Partial Dependency olmamalı.

Partial Dependency konusunu açıklamadan önce Dependency nedir ona bakmak gerekiyor. Yeniden karakterler tablosuna dönüp bir bakalım.

Tabloda id bilgileri eşsiz, ID kolonu bizim için Primary Key durumunda. Bir karakterin ismine erişmek istersem ya da oynadığı diziye, id bilgisini verip kaydı almam lazım. İşte bu duruma dependency deniliyor, diğer kolonlardaki verileri almak için ID kolonuna bağımlı durumdayız.

Şimdi çalışanlar isminde bir tablomuz olduğunu düşünelim. Bu tabloda ID, Name, Department bilgileri yer alıyor olsun. Bir de Tasks adında bir tablomuz olduğunu düşünelim. Her bir task’ı da ayrı kişilerin atayabileceğini düşünelim. Örneğin Işık Kontrol taskını bir kişi atayabiliyor, kırtasiye işleri taskını başka bir kişi.

Şimdi bu iki tablonun Assigned Tasks ismindeki bir tabloda şöyle buluştuğunu ve aşağıdaki şekilde bir çıktısı olduğunu düşünelim.

Employee ve Tasks arasında görebileceğiniz gibi bir many-to-many ilişki var. Biz her ne kadar bir id kolonuna sahip olsak da employee_id + task_id birleşimi bize daha iyi bir primary key seçeneği olarak ortaya çıkıyor. İşte bu noktada dikkatimizi Task_Assigner kolonu çekiyor. Az önce de belirttiğim gibi, bir taskı bir kişinin atama yetkisi varsa Task_Assigner sadece Task_Id ilişkili. Employee_Id ile bir birlikteliği yok. İşte tam bu noktada biz de diyebiliriz ki bu tabloda Partial Dependency var. Employee_id + task_id ortaklığındaki bir primary key kullanımında Task_Assigner sadece task_id ile ilişkili olacak ve bu da parçalı bağımlılık anlamına gelecek.

Buna çözüm olarak ise Task Assigner bilgisinin Assigned_Tasks tablosundan kaldırılması ve Tasks tablosuna eklenmesi yolu uygulanabilir.

3rd Normal Form

3rd Normal Form için yine 2 adet şart bulunmaktadır.

  1. 2nd Normal Form olmalı.
  2. Transitive Dependency olmamalı.

Transitive Dependency’nin ne olduğuna ve nasıl çözüleceğine bakalım şimdi.

Assigned_Tasks tablosunun aşağıdaki gibi olduğunu düşünelim:

Şimdi burayı incelediğimizde

  • employee_id + task_id primary key kombinasyonu üzerinden Task_Country bilgisini bilgisini bulabilirim.
  • Task_Country bilgisi üzerinden hangi task olduğunu bulamam çünkü aynı ülkede farklı tasklar olabilir.
  • Task_Country bilgisi üzerinden Task_Price_Currency bilgisini bulabilirim.

Bu noktada employee_id + task_id primary key kombinasyonu ile Task_Price_Currency arasında ortaya çıkan bağımlılığa Transitive Dependency adı veriliyor. Task_Price_Currency bilgisi Task_Country bilgisine göre değişkenlik gösteriyor. İşte bu şekilde primary key olmayan bir alan başka bir primary key olmayan alanının değerine karar verdiriyorsa buna Transitive Dependency adı veriliyor.

Bu durumu çözebilmek için de Task_Country ve Task_Price_Currency bilgilerini içeren ayrı bir tablo hazırlayıp Assigned_Tasks tablosunu da Task_Country üzerinden o tabloya bağlamak gerekiyor.

Bu yazıda anlatacaklarım bu kadar arkadaşlar. Başka bir yazıda görüşene kadar sağlıcakla kalın.