Bir uygulamanın kaderi çoğu zaman ilk satır kod yazılmadan önce, veritabanı şeması çizilirken belirlenir. Kötü kurgulanmış bir şema, aylar sonra kendini yavaş sorgular, tutarsız veriler ve her yeni özellikte artan bir baş ağrısı olarak gösterir. İyi tasarım ise sessizdir: fark edilmez çünkü işler yolunda gider. Bu yazıda, sağlıklı bir ilişkisel veritabanının temelini oluşturan normalizasyon (normalization) kavramını, adım adım ve gerçek hayattan örneklerle ele alacağız.

Veri Modeli Neden Her Şeyin Başıdır?
Yazılım katmanını istediğiniz zaman yeniden yazabilirsiniz; bir fonksiyonu değiştirmek, bir sınıfı bölmek genellikle birkaç saatlik iştir. Ancak üretimde milyonlarca satır veri biriktikten sonra veritabanı şemasını değiştirmek çok daha risklidir. Bu yüzden veri modeli, projenin en kalıcı ve en pahalı kararıdır. Berasoft'ta müşterilerimiz için özel e-ticaret ve kurumsal yazılım geliştirirken, işin ilk gününü genellikle veri modelini doğru çıkarmaya ayırırız; çünkü bu temel sağlamsa üzerine kurulan her şey daha az çatlar.
Normalizasyon, bu temeli sağlamlaştırmanın en bilinen yöntemidir. Amacı basittir: veriyi tekrarı en aza indirecek ve tutarsızlığı imkânsız kılacak biçimde tablolara bölmek.
Normalizasyon Tam Olarak Nedir?
Normalizasyon, veriyi mantıksal olarak birbirine bağlı parçalara ayırıp her bilgiyi yalnızca tek bir yerde tutma disiplinidir. Temel hedefi iki tür sorunu ortadan kaldırmaktır:
- Veri tekrarı (redundancy): Aynı bilginin birden fazla satırda kopyalanması, hem yer israfı hem de güncelleme kâbusudur.
- Anomali (anomaly): Ekleme, silme veya güncelleme sırasında verinin tutarsız hale gelmesi.
Bir müşteri tablosunda her siparişte müşterinin adını, telefonunu ve adresini tekrar tekrar yazdığınızı düşünün. Müşteri telefonunu değiştirdiğinde, o kişinin geçmiş tüm sipariş satırlarını tek tek güncellemeniz gerekir. Birini kaçırırsanız, veritabanınızda aynı kişinin iki farklı telefonu görünür. İşte normalizasyon bu felaketi önler.
Normalizasyon bir kuraldan çok bir düşünme biçimidir: "Bu bilgi mantıksal olarak neye ait?" sorusunu her alanda tekrar sormaktır.
Normal Formlar Adım Adım
Normalizasyon, "normal form" denilen kademeler halinde ilerler. Pratikte çoğu proje için üçüncü normal forma (3NF) kadar gitmek yeterlidir.
Birinci Normal Form (1NF)
Her hücre tek bir atomik değer içermelidir; bir alanda virgülle ayrılmış listeler barındırmak yasaktır. Örneğin bir urunler tablosunda "etiketler" alanına "kırmızı, indirimli, yeni" yazmak 1NF'yi ihlal eder. Bunun yerine etiketleri ayrı bir tabloya taşırsınız.
İkinci Normal Form (2NF)
Tablo 1NF olmalı ve tüm sütunlar birincil anahtarın (primary key) tamamına bağlı olmalıdır. Bu özellikle bileşik anahtarlarda önem kazanır. Örneğin siparis_kalemleri tablosunda anahtar (siparis_id, urun_id) ise, "urun_adi" alanı yalnızca urun_id'ye bağlıdır; dolayısıyla bu alan ürün tablosuna ait olmalıdır.
Üçüncü Normal Form (3NF)
Tablo 2NF olmalı ve hiçbir sütun, anahtar olmayan başka bir sütuna bağlı olmamalıdır (geçişli bağımlılık yasağı). Örneğin bir müşteri tablosunda "il_id" ile birlikte "il_adi" tutmak 3NF'yi ihlal eder; çünkü il_adi, il_id'ye bağlıdır. İl adları ayrı bir iller tablosunda yaşamalıdır.

Somut Bir Örnek: Sipariş Sistemi
Normalleştirilmiş bir e-ticaret şemasının çekirdeği aşağıdaki gibi görünür:
CREATE TABLE musteriler (
id INT PRIMARY KEY AUTO_INCREMENT,
ad_soyad VARCHAR(150),
email VARCHAR(190) UNIQUE
);
CREATE TABLE siparisler (
id INT PRIMARY KEY AUTO_INCREMENT,
musteri_id INT NOT NULL,
olusturma_tarihi DATETIME,
FOREIGN KEY (musteri_id) REFERENCES musteriler(id)
);
CREATE TABLE siparis_kalemleri (
siparis_id INT NOT NULL,
urun_id INT NOT NULL,
adet INT NOT NULL,
birim_fiyat DECIMAL(10,2) NOT NULL,
PRIMARY KEY (siparis_id, urun_id)
);
Dikkat edin: müşteri bilgisi yalnızca musteriler tablosunda yaşıyor, ürün adı burada tekrarlanmıyor ve fiyat sipariş anındaki değeriyle kalemde saklanıyor. Bu son ayrıntı önemlidir; ürün fiyatı sonradan değişse bile geçmiş siparişin tutarı korunur.
Normalizasyonun Sınırı: Denormalizasyon Ne Zaman Meşrudur?
Normalizasyon veri bütünlüğü için mükemmeldir, ancak her JOIN bir maliyettir. Çok yüksek okuma trafiği olan sistemlerde, bilinçli olarak bazı verileri tekrarlamak (denormalization) performans kazandırabilir. Örneğin bir sipariş listesinde müşteri adını her seferinde JOIN ile çekmek yerine, sipariş tablosuna kopyalanmış bir "musteri_adi" alanı tutmak sorguyu hızlandırabilir.
- Önce her zaman normalize edin; bu varsayılan tavırdır.
- Gerçek bir performans darboğazı ölçtüğünüzde denormalizasyonu değerlendirin.
- Denormalize ettiğinizde, kopyalanan veriyi güncel tutacak mekanizmayı (tetikleyici, uygulama katmanı) mutlaka kurun.
Erken denormalizasyon, erken optimizasyon kadar tehlikelidir. Önce doğru tasarlayın, sonra ölçtüğünüz gerçek soruna göre ödün verin.
Sık Yapılan Tasarım Hataları
- Her şeyi tek tabloya sıkıştırmak: "Kolaylık" için başlanan geniş tablolar, kısa sürede yönetilemez hale gelir.
- Yabancı anahtar kısıtlarını atlamak: Foreign key tanımlamamak, zamanla yetim kayıtlar (orphan records) doğurur.
- Anlamsal olmayan alan adları: "col1", "veri2" gibi isimler bir yıl sonra sizi bile şaşırtır.
- Tarih ve para birimlerini metin olarak saklamak: Uygun veri tiplerini kullanmak hem yer hem doğruluk kazandırır.
Sonuç
Normalizasyon, veritabanı tasarımının grameridir; kurallarını içselleştirdiğinizde tutarlı, esnek ve büyümeye hazır bir temel kurarsınız. Amaç kuralları körü körüne uygulamak değil, verinin doğasını anlamaktır: her bilgi nereye ait, hangi ilişki gerçek, nerede tekrar bir risk. Bu soruları erken sorduğunuzda, projeniz büyüdükçe sizi yormayan bir zemin elde edersiniz. Özel bir yazılım veya e-ticaret altyapısı kurarken veri modelinizi baştan sağlam oturtmak istiyorsanız, projenizi konuşalım; doğru temel, ilerideki her adımı ucuzlatır.
Bir sonraki projeniz için hazır mısınız?
Okuduklarınızı işinize uygulamak veya dijital dönüşümünüzü konuşmak isterseniz, ekibimiz bir mesaj uzağınızda.

Yorum Yap