Dr. Volkan Tunalı'nın Kişisel Blogu

Bilgisayar, Teknoloji, Bilim, Sanat

Archive for the ‘yazılım mühendisliği’ tag

Primary Key: Identity mi GUID mi?

leave a comment

Birincil Anahtar (Primary Key) olarak ne kullanılması gerektiği veritabanı tasarımında en sık karşılaşılan ve çözümü de çok kolay olmayan bir sorundur. Aslında veritabanı teorisi açısından en doğrusu Doğal Anahtar (Natural Key) olan kolonun birincil anahtar olarak kullanılması. Ancak pratikte bunun çeşitli sakıncaları bulunduğu için pek tercih edilmiyor. Günümüzün Nesne Yönelimli (Object Oriented) tasarımlarıyla daha iyi örtüştüğü için Doğal anahtar yerine Surrogate Key (harici, vekil anahtar) kullanımı daha çok tercih ediliyor. Özellikle de ORM (Object Relational Mapping) gibi veri ve iş mantığı katmanlarının kullanıldığı yazılım projeleri için Surrogate Key tek seçenek durumunda.

Surrogate Key’i kısaca tanımlamak gerekirse; kayıtlardaki veriyle hiçbir doğal bağlantısı ve ilgisi olmayan, tek amacı kayıtları eşsiz olarak nitelemek olan, genellikle de değerini veritabanı sisteminin kendisinin ürettiği tablo kolonudur. Çoğunlukla bu kolonun veri tipi olarak otomatik artan (Auto Increment, Identity, Sequence gibi) Integer ya da GUID (Globally Unique Identifier = Küresel Eşsiz Tanımlayıcı) tercih edilmektedir. İşte asıl sorun da bu noktada yaşanmakta: Bu ikisinden hangisini seçmeli ve neden? Ne yazık ki bu sorunun tek ve kesin bir yanıtı yok. Tasarlanmakta olan sistemin bugünkü ve de öngörülebilen gelecek ihtiyaçlarına bağlı olarak bir tercih yapılması gerekiyor. Bu tercihi yaparken her iki seçimin de avantaj ve dezavantajlarını ortaya koymak ve bunları iyi değerlendirmek gerekiyor. Bu makalede her iki veri tipini ayrı ayrı ele alacağız ve bir sonuca ulaşmaya çalışacağız.

GUID – Globally Unique Identifier

+ Bu veri tipinin en büyük avantajı evrensel olarak (ve en azından teoride) eşsiz değerlere sahip olması. Sadece bir tablodaki bütün satırlar değil, veritabanındaki tüm satırlar, hatta ve hatta evrendeki tüm tablolardaki tüm satırlar eşsiz kimliğe sahip olacak.

+ Eşsiz olma özelliğinden dolayı dağıtık durumdaki veritabanlarını bir gün gelip de merkezi hale getirmek gerektiğinde yani merge etmek (birleştirmek) gerektiğinde hiçbir sorun yaşanmadan, hiçbir dönüşüme gerek kalmadan bu işlem gerçekleştirilebilir. Dolayısıyla bu veri tipinin tercih edilmesinde kurulan sistemin böyle bir gereksinime cevap verebilir olmasının gerekliliği en önemli etkendir. (Örneğin MSSQL Server’da replikasyon yapıldığında eğer yok ise sistem her tabloya bir adet GUID kolon ekliyor.)

+ Programsal olarak üretilebildiği için veritabanına Insert işlemi sırasında değeri bilinebilir ve böylece Insert’ten sonra bir kez de en son kullanılmış değeri elde etmek için veritabanı sunucusuna bir erişime daha ihtiyaç duyulmaz. ORM açısından da bunun güzel bir özellik
olduğu düşünülebilir.

- GUID’nin en büyük dezavantajı veri boyutunun çok büyük olmasıdır. GUID’nin boyutu 128 bit = 16 byte’tır. Birincil anahtar olarak GUID kullanılan bir tablodaki diğer bütün index’lerin de bu 16 byte’ı taşıyacağı anlamına gelir. Sonuç olarak fazladan veritabanı boyutu ve disk alanı demektir. Elbette ki fazladan I/O işlemi = performans sıkıntısı.

- Veritabanı açısından değil belki ama yazılım geliştiriciler açısından B85E62C3-DC56-40C0-852A-49F759AC68FB gibi değerlerin debug etme işini epeyce zorlaştıracağı da bir gerçek.

- Çoğu veritabanı yönetim sistemi artık GUID veri tipini kendiliğinden destekliyor olsa da bunu doğal olarak desteklemeyen sistemlerde karakter veri tipi olarak tutulması gerekebilir (gerçek bir uygulamada böyle yapılmak zorunda kalındığını biliyorum).

- GUID’ler üretildiklerinde belli bir sıra takip etmezler, yani tamamen rastgele üretilirler. Yani, sonradan üretilen GUID, bir önceki GUID’den daha büyük olmak zorunda değildir. Bu durum bize Clustered Index şeklindeki birincil anahtar olarak tanımlanan GUID kolonlarda büyük bir
dezavantaj oluşturmaktadır. Bildiğiniz gibi Clustered Index demek, verilerin bu index’e göre veritabanı sayfaları üzerinde gerçekten doğal sırasıyla tutulması anlamına geliyor. Yani Clustered olmayan indexler gibi sadece index olmaktan ibaret değil. Bu durumda her sırasız Insert için tabloya ait sayfalarda yer değiştirme ve yer ayırma yapılması gerekiyor. Bu soruna çözüm olarak mesela MSSQL Server 2005′ten itibaren Sequential GUID gibi -bence zorlama ve uydurma- veri tipleri gelmekte ya da sıralı GUID üreten fonksiyonlar yazılmakta. Ek olarak, GUID türündeki birincil anahtarların Clustered yapılmaması da dikkat edilmesi gereken bir konu.

Identity Integer

+ Eğer 4 byte’lık Integer veri tipi kullanılırsa işlemci için en doğal ve en hızlı işlenen veri tipi olması bakımından ilişkisel veritabanı operasyonları için en uygun veri tipi olduğu söylenebilir.
16 byte genişliğinde GUID veri tipiyle kıyaslandığında veritabanı ve disk alanı bakımından da son derece avantajlı olduğu görülüyor.

+ Sıralı üretildikleri için GUID’deki Clustered Index problemi yaşanmıyor.

+ Program geliştiriciler için debug edilmesi, gözle takip edilmesi son derece kolaydır.

- Kayıt Insert edildikten sonra son üretilen Identity değeri elde etmek için sunucuya fazladan bir erişim yapmak ve işlem yaptırmak gerekiyor.

- Ayrık veritabanlarını merkezi olarak birleştirmek gerektiğinde çakışan değerler için ekstra uğraş gerekiyor.

Sonuç ve Değerlendirme

Dağıtık veritabanlarının replike edilmesi ya da merkezileştirilmesi gibi ihtiyaçlar söz konusu ise GUID büyük boyutuna ve diğer dezavantajlarına rağmen en iyi seçenek gibi görünüyor. Bunun dışında, 32 bit ya da gerçekten gerekli ise 64 bit Integer Identity şeklindeki Surrogate Key daha az masraflı, daha fazla sistem tarafından doğal olarak desteklenen ve daha pratik bir seçenek durumunda. Bu aşamada kişisel bir tercih belirtmem gerekirse mutlaka gerekmiyorsa GUID’den uzak durmayı seçiyorum.

Written by vtunali

Kasım 18th, 2009 at 12:13 am

Katmanlı Tasarım Yaklaşımı

leave a comment

Bir yazılım sistemini tasarlarken sistemi kullanıcı arayüzünden veritabanına kadar birbiriyle etkileşim halindeki çeşitli katmanlardan ya da üst üste bloklardan oluşan bir bütün olarak düşünmek gerekir. Burada en üst katman kullanıcı arayüzü, en alt katman ise veritabanı olarak düşünülebilir. Tabi ki her sistemin en alt katmanı veritabanı olmak zorunda olmadığı gibi en üst katmanın kullanıcı arayüzü olmak zorunda değildir. Ancak genelde böyle olduğunu düşünmek çok da yanlış olmayacaktır. Genellikle de veritabanı katmanının üzerinde bir Veri Erişim Katmanı (Data Access Layer – DAL), DAL’ın üzerinde ya da onunla bütünleşik bir Persistence katmanı, daha üzerinde de Business Layer dediğimiz sistem çapındaki işleyişi denetleyen katman yer alır. Sistemin gereksinimlerine göre bu katmanların sayısı arttırılabilir ya da azaltılabilir.

Yazılım sistemi geliştirirken katmanlardan oluşan yapısal bir düzen oluşturmanın çeşitli avantajları vardır:

  • Fonksiyonları belirli katmanları kodlamak daha kolaydır ve daha az hata ile sonuçlanır.
  • Sistemi bu katmanları kullanarak oluşturmak daha az karmaşık ve daha az zahmetlidir.
  • Sistemi yeni gereksinimlere ve değişikliklere adapte etmek daha kolaydır.
  • Hata (bug) bulmak ve gidermek daha kolaydır.
  • Sistemin başka yazılımcılar tarafından anlaşılması ve öğrenilmesi daha kolaydır.
  • Herhangi iki katman arasına yeni bir katman ilave etmek ya da aradaki bir katmanı çıkartmak katmanlı yapı kullanılmayan bir sistemde aynı amaca yönelik yapılması gerekecek revizyona göre genellikle daha az maliyetlidir.

Sistemde yer alacak katmanları belirlerken ve tasarlarken de şu ilkeler doğrultusunda hareket edilmelidir:

  • Her katman sadece belirli bir fonksiyonu ya da fonksiyon grubunu içermelidir. Farklılaşan fonksiyonlar söz konusu olduğunda başka bir katmana taşınmalı ya da yeni bir katman yaratılmalıdır. Dolayısıyla katmanların sayısı fonksiyonalite açısından farklılaşan ünitelerin sayısı olacaktır.
  • Katmanlar arası arabirimler tasarlanırken bilgi akışı minimum düzeyde olacak şekilde tasarlanmalı.
  • Tabi ki her alt katman üstündeki katmana bir servis sağlamalı. Tersi yönde bir hizmet sunumu ya da bağımlılık söz konusu olamaz; böyle bir durum oluşuyorsa tasarımda bir sorun var demektir.
  • Bir katman genellikle altındaki bir katmandan servis almalı, çok gerekmedikçe bu katmanı atlayıp daha alt bir katman ile haberleşmemelidir. Ama buna istisnalar söz konusu olabilir.

Özetle, yazılım geliştirirken fonksiyonel birimlerin birbirinden kesin ve net sınırlarla ayrıldığı katmanlı bir yaklaşım projenin ilk zamanlarında uğraştırıcı ve zaman alıcı görünse de sonrasında getireceği avantajlar ile bu zaman kaybı fazlasıyla telafi olacak, bu yaklaşımın yararları sistemin geliştirilme sürecinde görülecektir.

Written by vtunali

Haziran 4th, 2009 at 1:04 am

Kritik Kütle

leave a comment

Kritik kütle, yazılımın kaynak kodunun komple yeni baştan yazılmadıkça etkin bir şekilde yönetilemeyecek kadar aşırı büyük boyutlara ulaştığı Yazılım Yaşam Döngüsü aşamasını tanımlayan bir Yazılım Mühendisliği terimidir. Bir tanımlama da şu şekilde yapılabilir: mevcut bir hatayı (bug) gidermek yeni ve daha büyük bir hataya yol açıyorsa, yazılım artık kritik kütleye ulaşmış demektir. Genellike kritik kütle aşamasındaki bir yazılım iyileştirilmeye çalışılmaz; yazılıma son verilir ve yeni baştan geliştirilir.

Hatalı planlama, yazılımcı sirkülasyonu nedeniyle sürekli yeni yazılımcıların projeyi ele alması, yetersiz dokümantasyon, kopyala-yapıştır tarzı kötü programlama alışkanlıkları gibi temel nedenler bir yazılım projesinin Kritik Kütle aşamasına gelmesine neden olmaktadır.

Genelde masum ve düzgün planlanmış gibi başlayan bir yazılım projesi zaman içerisinde özensizce eklenen yeni özellikler nedeniyle kontrolsüz bir şekilde büyür ve bu büyüme farkedilmeyen hataları ve çözülemeyen sıkıntıları da beraberinde getirir. Ya da bazen bir an önce çalışan bir ürün çıkartma derdiyle çabucak bir geliştirme yapılır, bütün eksik ve özensiz tasarımına rağmen sistem çalışıyor ve müşteriyi memnun ediyordur. Eksikleri giderilmeden ve iyileştirilmeden yeni özelliklerin bu baştan sorunlu tasarım üzerine eklenmesinin sonucunda kritik kütle yine kaçınılmazdır.

Çoğunlukla yine aceleci, özensiz ve düzensiz geliştirme süreçleri nedeniyle dokümantasyon eksikliğinin koddan giderilmeye çalışılması, revize edilecek kodu yazanın artık projede bulunmaması sonucunda yeni programcıların eksik bilgiyle yaptığı eklenti ve revizyonlar da zaman içerisinde mevcut kodu iyice içinden çıkılmaz hale getirebilir. Bir de buna suya sabuna dokunmadan sorunları bir an önce çözmek için kopyala-yapıştır programcılık yapılması eklenince yazılım sistemi artık devam ettirilebilir, desteklenebilir, kolay revize edilebilir (maintainable) bir sistem olmaktan çıkmaktadır.

Written by vtunali

Ocak 29th, 2009 at 8:55 am