28 Eylül 2010 Salı

Relations (Veritabanı ilişkileri)

Bu konudan önce,  Normalization başlıklı yazıyı okumanızı öneririm.

Relation, veri tabanı tasarımcılarının, normalize edilmiş bir veri tabanı yaratırken, veri tekrarını önlemek için kullandıkları bir araçtır.  Basitçe, relation, tekrarlanan verinin, veritabanında hangi tabloların, hangi alanlarında bulunacağını gösteren bir yoldur.
Ana verinin  bulunduğu tabloya parent table denir. Normalization yazısında örneğini yaptığımız ve müşteri bilgilerinin tutulduğu Customer tablosu, bir parent tablodur.

Parent tabloda bulunan asıl veriye ulaşmak için pointerların tutulduğu tabloya Child tablo denir.  Parent ve Child tablolar birbirleriyle ilişkilidirler.  Yine normalizasyon yazısındaki, normalize edilmiş Order tablosu, bir child tablodur.  Order tablosundaki CustomerID ile Customer tablosundaki CustomerID alanıyla ilişkilidir.

Customer tablosundaki, CustomerID nin her bir müşteri için ayrı olduğunu ve Customer ID den müşterinin tüm bilgilerine ulaşabileceğimizi söylemiştik. Yani Customer tablosundaki CustomerID unique'dir ve başka tablolar ile CustomerID  alanı ile ilişkilendirilir. Bu neden Customer tablosundaki CustomerID'yi primary key yapabiliriz.

Bu durumda, diğer tablolardaki (Örneğin Order tablosundaki) CustomerID alanı, Customer tablosundaki, CustomerID yi işaret eder ve buna da foreign key denir.



Birkaç  çeşit veritabanı ilişkisi vardır.
One-To-One (1 - 1)  : Parent tablodaki bir satıra karşılık, child tablodada sadece 1 satır bulunur.  Örneğin Müşteri tablosundaki adres bilgisini başka bir tabloda tutsaydık ve sadece tek bir adres girilmesine izin verseydik, Müşteri ve Adres tablosu arasında "Bire - Bir" ilişki kuracaktık.

One-To-Many (1 - *) : Parent tablodaki bir satıra karşılık, child tabloda birden fazla satır olabilir. Tıpkı Müşteri ve Sipariş tablosundaki ilişki gibi. Bir müşteri 1 veya daha fazla sipariş verebilir.

Many-To-Many (*-*) : Parent tablodaki bir satıra karşılık, child tabloda birden fazla satır olabildiği gibi, child tablodaki bir satıra karşılık da, parent tabloda birden fazla satır olabilir. Many-To-Many ilişki aslında birden çok One-To-Many ilişkinin bir araya gelmesinden oluşur. Bu ilişkileri bir araya getirecek olan ve  Many-To-Many ilişkiyi sağlayacak olan bir ara bağlantı tablosudur. Bu tablo sadece ilişkide gerekli olan alanları tutar.

Aşağıdaki şekil, many to many ilişki kurulmuş bir örnek gösteriyor. Asp.Net 'in  user - role leri yönetmemiz için hazırladığı aspnetservices veri tabanından bir gösterim.

Users ve Roles tabloları var. Bir kullanıcı birden fazla role'de yer alabileceği gibi, bir role için de birden fazla kullanıcı tanımlanabilir.
Kullanıcı bilgileri aspnet_Users tablosunda tutuluyor. Yanında anahtar resmi görünen UserId alanı, tablonun primary key'i.
Role'ler, aspnet_Roles tablosunda tutuluyor. RoleId alanı ise, bu tablonun primary key'i.
Many-To-Many ilişkiyi sağlayan ise aspnet_UserInRoles tablosu. Bu tabloda sadece her iki tablonun da primary key'leri tutuluyor.

Bu gösterimi, SQL Server Management Studio'da, "Database Diagram" kullanarak hazırladım.  Tüm veri tabanı tasarım toolları tablolar arasındaki ilişkinin varlığını araya çizgi çekerek ifade eder. Sadece ilişki türleri biraz farklı gösterilebilir. SQL Server,  Tek bir kayıt olacağını gösterdiği yerler için anahtar şeklini, çoklu kayıt olacak yerlerde ise sonsuz işaretini kullanmış. 

aspnet_Users ile aspnet_UsersInRoles arasındaki ilişkide,  aspnet_Users tarafında bir anahtar işareti görünüyor. Bu, ilişkinin o tarafında tek bir satırın olacağını gösteriyor.  aspnet_UsersInRoles tablosuna bağlanan yerde ise bir sonsuz işareti var, bu tabloda bir kullanıcıya karşılık istediğimiz kadar role ekleyebileceğimiz anlamına geliyor.

Aynı türde ilişki aspnet_Roles ve aspnet_UsersInRoles tabloları arasında da kurulmuş. Bu ilişki de bir role'ün birden fazla kullanıcıya verilebileceğini ifade ediyor.
Sonuç olarak, bu 3 tablo ile, bir kullanıcıya birden fazla görev verilebilirken, bir görevde de birden fazla kullanıcının olabileceği bir  yapı sağlanmış oluyor.


Primary key, foreign key ve ilişkilerin SQL Server'da nasıl tanımlandığına daha sonra değineceğiz.

27 Eylül 2010 Pazartesi

Normalizasyon

RDBMS (Relational Database Management System) ın en önemli kavramlarından biridir normalizasyon(normalization).

Normalizasyonun ne olduğuna örnek üzerinden bakalım.

Diyelim ki bir Customer tablomuz var. İçerisinde Müşteri Numarası, Adı - Soyadı ve Adres alanları var.

Customer Tablosu

Customer ID FirstName LastName Address
1 Ali Veli Deneme Mah. Deneme Sk. No:5/6 Kadıköy / İstanbul
2 Can Demir Test Mah. Deneme Sk. No:5/6  Lüleburgaz / Kırklareli
3 Birsen Tunç 1825 Sk. No:5/6 Konak / İzmir
4 Erdem Yazar Test Sk. No:5/6  Şişli / İstanbul

Eğer bir müşterinin siparişi için bir tablomuz varsa,  sipariş özeti için  bize gerekli olan bilgiler Müşterinin Adı, Soyadı, Adresi, Sipariş Tarihi ve Sipariş Tutarı.

Müşteri bilgilerini "Sipariş " bilgilerini tuttuğumuz Order tablosuna da kopyalayacak mıyız o zaman?  Müşteri bilgilerini Order tablosunda da taşınırsa ne olur peki? Bir müşterinin her bir siparişi için, Order tablosunda müşterinin tüm bilgileri tekrarlanır.   Bu  Order tablosunun gereksiz yere fazla bilgi ile dolmasına ve verilen diskte gerektiğinden fazla yer kaplamasına neden olacaktır. Tabii bu bilgiler sadece tabloda değil, aynı zamanda index tablolarında da tekrarlanacaktır.  Ancak daha da önemlisi, müşterinin bilgilerinde bir değişiklik olduğunda sadece Customer tablosunu güncellememiz yeterli olmayacak, Order tablosunda  da o müşteriye ait tüm sipariş kayıtlarını bulmamız ve onları da güncellememiz gerekecektir. Bunu unutmamız durumunda ve update işlemi sırasında bir hata ile karşılaşırsak ve bu da kayıtların bir kısmını  güncelleyip, bir kısmını da güncellemez ise ortaya çıkacak  karmaşayı düşünebiliyor musunuz?

İşte tüm  bu karmaşadan ve sorunlardan kaçınmak için tablolar normalize olarak tutulur.  Normalizasyon, bir grup tablo tanımlama kuralıdır. Normalizasyon kurallarına göre, tablolar tasarlanırken, bağlantılı oldukları tabloların her birinden sadece tek bir alan  içerirler.  Tabii bu alan tek olunca, bağlantılı oldukları tablodaki doğru kaydı bulabilecek bir bilgi tutmalıdırılar. Örneğin sipariş tablosundan, müşteri bilgisi olarak müşterinin sadece adını tutmamız, aynı isimde birden fazla müşteri olacağı için bir işe yaramaz. Bunun için Müşteri numarası gibi, her bir müşteri için tek olan ve değişmeyecek bir alan seçilmelidir.

İşte normalize edilmiş Sipariş tablosu :


OrderID CustomerID OrderDate OrderAmount
1001 1 15.02.2010 150
1002 3 15.02.2010 250
1003 1 16.02.2010 500
1004 2 17.02.2010 100
1005 4 18.02.2010 1250
1006 2 19.02.2010 85
1007 2 20.02.2010 950
1008 1 21.02.2010 120



Normalizasyonun da çeşitleri vardır. 3rd Normal Form, 4th Normal Form gibi.
Bu detaylara daha sonra gireceğiz. Ancak akılda tutulması gereken şey, normalizasyon, veri tekrarının önlemek için konulan bir veri tabanı tasarım kuralı olmasıdır. .

Normalizasyonun tam tersine, yani bir tabloda, diğer tablolardaki  birçok bilginin tekrarlandığı, kayıt tekrarına izin verilen tablolara denormalize edilmiş tablolar denir.
Veri güncellemesi yapılmayan, daha çok raporlama için kullanılan veri tabanlarında, hızlı sorgulama yapılmak için tablolar denormalize edilebilir.

Bu da denormalize edilmiş bir sipariş tablosu


OrderID CustomerID OrderDate OrderAmount FirstName LastName Address
1001 1 15.02.2010 150 Ali Veli Deneme Mah. Deneme Sk. No:5/6 Kadıköy / İstanbul
1002 3 15.02.2010 250 Birsen Tunç 1825 Sk. No:5/6 Konak / İzmir
1003 1 16.02.2010 500 Ali Veli Deneme Mah. Deneme Sk. No:5/6 Kadıköy / İstanbul
1004 2 17.02.2010 100 Can Demir Test Mah. Deneme Sk. No:5/6  Lüleburgaz / Kırklareli
1005 4 18.02.2010 1250 Erdem Yazar Test Sk. No:5/6 Şişli / İstanbul
1006 2 19.02.2010 85 Can Demir Test Mah. Deneme Sk. No:5/6  Lüleburgaz / Kırklareli
1007 2 20.02.2010 950 Can Demir Test Mah. Deneme Sk. No:5/6  Lüleburgaz / Kırklareli
1008 1 21.02.2010 120 Ali Veli Deneme Mah. Deneme Sk. No:5/6 Kadıköy / İstanbul

Normalizasyon ile ilgili daha detaylı bilgiler yakında burada olacak.

"Ralph Kimball - The Date Warehouse Toolkit" dan notlar - 1

Kimball'ın modeli, son kullanıcının çok zorlanmadan kullanabileceği ama en önemlisi rahat ve kolay geliştirilebilecek bir tasarım yapmak üzerine kurulu. İşte "The Data Warehouse Toolkit" kitabından birkaç not.

  • "Presentation area", ilişkisel veri tabanına bağlı ise bu boyutlu(dimensional) modellenmiş tablolara "star schema" denir. "Presentation area", multidimensional bir veritabanı veya OLAP'a bağlı ise, data küplerde saklanıyordur.
  • İşin gereksinimlerine odaklan ve modelini ona göre kur, veri yapına göre değil.
  • Kolay development'a odaklan.
  • En iyi özellikler (attribute) metin olanlarıdır.
  • Dimension tabloları, denormalize edilmiş tablolardır.
  • Hiyerarşik veri tutan tabloları denormalize etmek ve bu tür tablolarda "snowflake schema" dan kaçınmak gerekli.
  • Kullanıcıya atomik data vermek gerekmese bile, datayı atomik seviyede tutmakta fayda var.
  • Dimension veya fact tablolarına yeni bir attribute eklemek gerekirse, eski tarihli datalar için bu attributelere verinin olmadığına dair anlamlı bir bilgi yaz.
  • Fact tablolarında en detayda oranlar değil, toplamlar olsun. Daha sonra toplamların oranını al, oranların toplamını değil.
  • DATE dimension tablosu tanımla. Bu tablo veri tarihçesinin tutulmasını ve raporların kolay alınmasını sağlayacak. Date tablosundaki anahtar alan tarih tipinde değil, bir integer. Bunun integer olmasının ararlarını daha sonra göreceğiz. Date dimension içerisinde, raporlarda kullanılabilecek ve zaman ile ifade edilen her türlü şey olabilir. Günün adı (pazartesi, salı vb) , Satış sezonu (İlkbahar - yaz, sonbahar - kış), ayın kaçıncı günü, yılın kaçıncı günü, tatil gibi. Date Dimension Tablosunun Alanları : "Date Key, Date, Day of week, Month, Year, Quarter, Full Date Description, Day number in calendar month, Day number in calendar year, Sales Season" gibi olabilir.

Kaçınılması gereken sık rastlanan tuzaklar :
  • İş gereksinimleri ve amaçlarına odaklanmak yerine teknoloji ve dataya takılmayın.
  • Veri ambarı işini destekleyenlerin makul bir yönetim vizyonuna sahip olmaması veya işi yeterince sahiplenmemesi sorun olabilir.
  • Kolay yönetilebilir, ilgi çekici devam edecek proje yerine, çok büyük, yıllar sürecek ve çaba gerektiren projeler ile mücadele etmeyin.
  • Dimensional modellere dayanan kullanışlı bir presentation yaratmadan, normalize edilmiş veri yapılarına enerji harcamayın.
  • Arka plandaki operasyonel performans ve geliştirme kolaylığından fazla, ön yüzün kullanım kolaylığı ve performansına önem vermeyin.
  • Belki sorgulanabilir diye, görsel katmanı fazla karmaşık yapmayın. Veritabanı tasarımcıları, karmaşık sorgular yerine, kullanıcıların basit ihtiyaçlarını karşılarlar ise daha fazla takdir edilirler.
  • Ortak, birbirine bağlanabilen dimension tabloları içeren veri mimarisi yerine tek başına kullanılabilecek dimension tablolarından oluşan yapılar kurun.
  • Görsel alandaki dimension yapılarına sadece özet data yükleyin.
  • Bir işin gereksinimlerinin, analitiğinin ve altındaki verinin ve işin yapıldığı teknolojinin statik olduğunu varsayın.
  • Veri ambarının başarısının kullanıcının işi benimsemesiyle ilgili olduğunu unutmayın. Kullanıcı, veri ambarını karar vermenin temeli olarak kabul etmezse tüm çabalarınız boşa gider.