Normalizasyon Nedir?
Normalizasyon Nedir?
Normalizasyon, ilişkisel veritabanlarında verilerin daha düzenli, tutarlı ve yönetilebilir bir yapıda saklanmasını sağlayan veritabanı tasarım yöntemidir.
Temel amaç, aynı bilginin gereksiz yere birden fazla yerde tutulmasını önlemek ve tablolar arasındaki ilişkileri doğru şekilde oluşturmaktır.
Bir veritabanı projesine başlarken bütün bilgileri tek bir tabloda tutmak ilk bakışta kolay görünebilir. Ancak veri miktarı arttıkça bu yaklaşım birçok probleme neden olur.
Örneğin bir satış sisteminde aşağıdaki bilgilerin tamamının tek tabloda tutulduğunu düşünelim:
| Sipariş No | Müşteri Adı | Telefon | Ürün | Kategori | Adet | Fiyat |
|---|---|---|---|---|---|---|
| 1001 | Ahmet Yılmaz | 0555 111 22 33 | Klavye | Bilgisayar | 1 | 750 |
| 1002 | Ahmet Yılmaz | 0555 111 22 33 | Mouse | Bilgisayar | 2 | 400 |
| 1003 | Mehmet Kaya | 0555 444 55 66 | Klavye | Bilgisayar | 1 | 750 |
Bu tablo küçük bir sistemde çalışabilir. Ancak veri sayısı arttıkça bazı önemli sorunlar ortaya çıkar.
Ahmet Yılmaz her sipariş verdiğinde adı ve telefon numarası tekrar kaydedilmektedir. Klavye ürünü her satıldığında ürün adı, kategori ve fiyat bilgileri yeniden yazılmaktadır.
Normalizasyon, bu tekrarları azaltmak için verileri mantıksal tablolara ayırır.
Örneğin sistem şu tablolardan oluşabilir:
- Müşteriler
- Ürünler
- Kategoriler
- Siparişler
- Sipariş Detayları
Böylece her bilgi kendi tablosunda yalnızca ihtiyaç duyulduğu kadar tutulur.
Normalizasyon Neden Gereklidir?
Normalizasyonun en önemli amacı veri tekrarını azaltmaktır. Ancak sağladığı avantaj yalnızca bundan ibaret değildir.
Veri Tekrarını Azaltır
Aynı müşteri bilgisinin yüzlerce sipariş kaydında tekrar saklanması yerine müşteri bilgisi yalnızca müşteri tablosunda tutulur.
Örneğin:
Musteriler
------------------------
Id
AdSoyad
Telefon
EPosta
Sipariş tablosunda ise müşterinin tüm bilgilerini tekrar saklamak yerine yalnızca müşteri kimliği tutulur:
Siparisler
------------------------
Id
MusteriId
SiparisTarihi
Bu yapı sayesinde bir müşteri 100 sipariş verse bile adı ve telefon numarası 100 kez tekrar kaydedilmez.
Güncelleme Problemlerini Önler
Normalizasyon yapılmamış bir tabloda aynı bilgi birden fazla satırda bulunabilir.
Örneğin Ahmet Yılmaz’ın telefon numarası 50 farklı sipariş satırında kayıtlıysa, telefon numarası değiştiğinde 50 satırın güncellenmesi gerekir.
Bu satırlardan yalnızca 49 tanesi güncellenirse veritabanında tutarsızlık oluşur.
Bir kayıtta:
0555 111 22 33
başka bir kayıtta:
0555 999 88 77
değeri bulunabilir.
Hangisinin güncel olduğu artık belli değildir.
Normalleştirilmiş yapıda telefon numarası yalnızca müşteri tablosunda tutulduğu için tek bir kayıt güncellenir:
UPDATE Musteriler
SET Telefon = '0555 999 88 77'
WHERE Id = 15;
Bu işlemden sonra müşteriye bağlı bütün siparişlerde güncel bilgi kullanılabilir.
Silme Problemlerini Önler
Normalizasyon yapılmamış tablolarda bir kaydın silinmesi, aslında korunması gereken başka bilgilerin de kaybolmasına neden olabilir.
Örneğin bir ürün bilgisi yalnızca sipariş tablosunda tutuluyorsa ve o ürüne ait son sipariş silinirse ürün bilgisi de tamamen kaybolabilir.
Normalleştirilmiş yapıda ürün ayrı bir tabloda bulunur:
Urunler
------------------------
Id
UrunAdi
KategoriId
Fiyat
Bir sipariş silinse bile ürün bilgisi sistemde kalmaya devam eder.
Ekleme Problemlerini Önler
Normalizasyon yapılmamış bir sistemde bazen başka bir bilgi girilmeden yeni kayıt eklemek mümkün olmaz.
Örneğin ürünler yalnızca sipariş tablosunda tutuluyorsa henüz hiç satılmamış yeni bir ürünü sisteme nasıl ekleyeceğiz?
Normalleştirilmiş yapıda ürünler ayrı tabloda bulunduğu için sipariş verilmesini beklemeden yeni ürün eklenebilir:
INSERT INTO Urunler
(
UrunAdi,
KategoriId,
Fiyat
)
VALUES
(
'Mekanik Klavye',
1,
1750
);
Normal Formlar Nelerdir?
Normalizasyon işlemi belirli kurallar doğrultusunda gerçekleştirilir. Bu kurallar “Normal Form” olarak adlandırılır.
En çok kullanılan normal formlar şunlardır:
- Birinci Normal Form — 1NF
- İkinci Normal Form — 2NF
- Üçüncü Normal Form — 3NF
Daha ileri seviyelerde BCNF, 4NF ve 5NF gibi normal formlar da bulunmaktadır. Ancak birçok ticari uygulamada doğru uygulanmış bir 3NF yapısı yeterli olmaktadır.
1NF — Birinci Normal Form Nedir?
Bir tablonun Birinci Normal Form’a uygun olabilmesi için her sütundaki değerlerin bölünemez, yani atomik olması gerekir.
Bir hücre içerisinde birden fazla değer bulunmamalıdır.
Yanlış bir örnek:
| MusteriId | MusteriAdi | Telefonlar |
|---|---|---|
| 1 | Ahmet Yılmaz | 0555 111 22 33, 0532 444 55 66 |
| 2 | Mehmet Kaya | 0542 777 88 99 |
Bu tabloda Telefonlar sütununda birden fazla telefon numarası bulunmaktadır.
Bu yapı bazı sorguları zorlaştırır.
Örneğin belirli bir telefon numarasına sahip müşteriyi bulmak için şu şekilde bir sorgu yazmak gerekebilir:
SELECT *
FROM Musteriler
WHERE Telefonlar LIKE '%0532 444 55 66%';
Bu yöntem sağlıklı bir ilişkisel veritabanı tasarımı değildir.
Daha doğru yapı, telefon numaralarını ayrı bir tabloda tutmaktır:
Musteriler
------------------------
Id
AdSoyad
MusteriTelefonlari
------------------------
Id
MusteriId
Telefon
Örnek veriler:
| Id | MusteriId | Telefon |
|---|---|---|
| 1 | 1 | 0555 111 22 33 |
| 2 | 1 | 0532 444 55 66 |
| 3 | 2 | 0542 777 88 99 |
Artık bir müşterinin istediğimiz kadar telefon numarası olabilir.
SQL Server üzerinde tablolar şu şekilde oluşturulabilir:
CREATE TABLE Musteriler
(
Id INT IDENTITY(1,1) PRIMARY KEY,
AdSoyad VARCHAR(100) NOT NULL
);
CREATE TABLE MusteriTelefonlari
(
Id INT IDENTITY(1,1) PRIMARY KEY,
MusteriId INT NOT NULL,
Telefon VARCHAR(20) NOT NULL,
CONSTRAINT FK_MusteriTelefonlari_Musteriler
FOREIGN KEY (MusteriId)
REFERENCES Musteriler(Id)
);
Bu yapı Birinci Normal Form’a daha uygundur.
2NF — İkinci Normal Form Nedir?
Bir tablonun İkinci Normal Form’a uygun olması için öncelikle 1NF kurallarını sağlaması gerekir.
Ayrıca tabloda birleşik birincil anahtar varsa, anahtar olmayan bütün sütunlar birleşik anahtarın tamamına bağlı olmalıdır.
Bunu bir örnekle açıklayalım.
Bir sipariş detay tablomuz olduğunu düşünelim:
| SiparisId | UrunId | UrunAdi | Adet | BirimFiyat |
|---|---|---|---|---|
| 1001 | 10 | Klavye | 2 | 750 |
| 1001 | 15 | Mouse | 1 | 400 |
Tablonun anahtarı şu iki alandan oluşabilir:
SiparisId + UrunId
Ancak UrunAdi yalnızca UrunId alanına bağlıdır.
Ürün adını öğrenmek için sipariş numarasına ihtiyacımız yoktur.
Bu nedenle ürün bilgileri ayrı bir tabloya taşınmalıdır:
Urunler
------------------------
Id
UrunAdi
Fiyat
Sipariş detay tablosu ise şu şekilde düzenlenebilir:
SiparisDetaylari
------------------------
SiparisId
UrunId
Adet
BirimFiyat
Buradaki önemli nokta BirimFiyat alanıdır.
İlk bakışta fiyatın ürün tablosunda tutulması yeterli görülebilir. Ancak ürün fiyatları zaman içerisinde değişebilir.
Bugün 750 TL olan bir ürün gelecek ay 900 TL olabilir.
Eski siparişin toplamını doğru hesaplayabilmek için satış anındaki fiyat sipariş detayında saklanabilir.
Bu durum normalizasyon hatası değildir. Çünkü burada saklanan bilgi ürünün güncel fiyatı değil, ilgili siparişte uygulanan satış fiyatıdır.
3NF — Üçüncü Normal Form Nedir?
Bir tablonun Üçüncü Normal Form’a uygun olabilmesi için öncelikle 1NF ve 2NF kurallarını sağlaması gerekir.
Bunun yanında anahtar olmayan bir sütun, başka bir anahtar olmayan sütuna bağlı olmamalıdır.
Örneğin aşağıdaki ürün tablosunu ele alalım:
| UrunId | UrunAdi | KategoriId | KategoriAdi |
|---|---|---|---|
| 1 | Klavye | 10 | Bilgisayar |
| 2 | Mouse | 10 | Bilgisayar |
| 3 | Telefon | 20 | Elektronik |
Burada:
- UrunId, ürünün anahtarıdır.
- KategoriId, ürünün kategorisini belirtir.
- KategoriAdi ise doğrudan ürüne değil, KategoriId alanına bağlıdır.
Yani şu bağımlılık bulunmaktadır:
UrunId → KategoriId → KategoriAdi
Bu tür yapıya geçişli bağımlılık denir.
Daha doğru yapı şöyledir:
Kategoriler
------------------------
Id
KategoriAdi
Urunler
------------------------
Id
UrunAdi
KategoriId
Fiyat
SQL karşılığı:
CREATE TABLE Kategoriler
(
Id INT IDENTITY(1,1) PRIMARY KEY,
KategoriAdi VARCHAR(100) NOT NULL
);
CREATE TABLE Urunler
(
Id INT IDENTITY(1,1) PRIMARY KEY,
UrunAdi VARCHAR(150) NOT NULL,
KategoriId INT NOT NULL,
Fiyat DECIMAL(18,2) NOT NULL,
CONSTRAINT FK_Urunler_Kategoriler
FOREIGN KEY (KategoriId)
REFERENCES Kategoriler(Id)
);
Artık kategori adı yalnızca kategori tablosunda tutulmaktadır.
Bir kategori adı değiştirileceğinde yalnızca tek bir kayıt güncellenir:
UPDATE Kategoriler
SET KategoriAdi = 'Bilgisayar ve Aksesuar'
WHERE Id = 10;
Bu kategoriye bağlı bütün ürünler yeni kategori adını otomatik olarak kullanır.
Normalizasyon Öncesi ve Sonrası Örneği
Normalizasyon yapılmamış bir sipariş tablosu şöyle olabilir:
Siparisler
---------------------------------------------------------
SiparisId
SiparisTarihi
MusteriAdi
MusteriTelefon
MusteriAdres
UrunAdi
KategoriAdi
Adet
Fiyat
Bu tabloda çok fazla tekrar oluşacaktır.
Aynı müşteri her siparişte tekrar yazılır.
Aynı ürün her satışta tekrar yazılır.
Aynı kategori yüzlerce üründe tekrar tutulur.
Normalizasyon sonrasında sistem şu tablolara ayrılabilir:
Musteriler
------------------------
Id
AdSoyad
Telefon
Adres
Kategoriler
------------------------
Id
KategoriAdi
Urunler
------------------------
Id
UrunAdi
KategoriId
Fiyat
Siparisler
------------------------
Id
MusteriId
SiparisTarihi
SiparisDetaylari
------------------------
Id
SiparisId
UrunId
Adet
BirimFiyat
Artık tablolar birbirlerine Primary Key ve Foreign Key alanlarıyla bağlanabilir.
Örnek bir sorgu:
SELECT
s.Id AS SiparisNo,
s.SiparisTarihi,
m.AdSoyad AS Musteri,
u.UrunAdi,
k.KategoriAdi,
sd.Adet,
sd.BirimFiyat,
sd.Adet * sd.BirimFiyat AS Toplam
FROM Siparisler s
INNER JOIN Musteriler m
ON m.Id = s.MusteriId
INNER JOIN SiparisDetaylari sd
ON sd.SiparisId = s.Id
INNER JOIN Urunler u
ON u.Id = sd.UrunId
INNER JOIN Kategoriler k
ON k.Id = u.KategoriId;
Bu sorgu farklı tablolardaki ilişkili bilgileri bir araya getirerek sipariş listesini oluşturur.
Normalizasyonun Avantajları Nelerdir?
Doğru uygulanmış normalizasyon birçok avantaj sağlar.
Daha Az Veri Tekrarı
Aynı bilgi gereksiz yere farklı kayıtlarda tekrar saklanmaz.
Bu durum özellikle milyonlarca kayıt bulunan sistemlerde ciddi depolama avantajı sağlayabilir.
Daha Tutarlı Veriler
Bir bilgi tek bir yerde tutulduğu için farklı tablolarda veya satırlarda çelişkili değerlerin oluşma ihtimali azalır.
Daha Kolay Güncelleme
Müşteri, kategori veya ürün gibi bilgiler tek bir noktadan güncellenebilir.
Daha Güvenli Veri Bütünlüğü
Primary Key, Foreign Key ve Unique Constraint gibi veritabanı kuralları daha etkili şekilde kullanılabilir.
Örneğin:
ALTER TABLE Urunler
ADD CONSTRAINT FK_Urunler_Kategoriler
FOREIGN KEY (KategoriId)
REFERENCES Kategoriler(Id);
Bu constraint sayesinde sistemde bulunmayan bir kategoriye ürün eklenmesi engellenebilir.
Daha Kolay Bakım
Tabloların sorumlulukları daha net olduğu için uygulamanın geliştirilmesi ve bakımı kolaylaşır.
Normalizasyonun Dezavantajları Var mı?
Normalizasyon genellikle doğru bir veritabanı tasarımı için gereklidir. Ancak her durumda mümkün olan en fazla sayıda tablo oluşturmak doğru değildir.
Aşırı normalizasyon, çok sayıda tablo ve JOIN işlemi oluşmasına neden olabilir.
Örneğin basit bir rapor için 15 farklı tablonun birleştirilmesi gerekiyorsa sorgular karmaşık hale gelebilir.
SELECT ...
FROM Tablo1
INNER JOIN Tablo2 ON ...
INNER JOIN Tablo3 ON ...
INNER JOIN Tablo4 ON ...
INNER JOIN Tablo5 ON ...
Bu nedenle veritabanı tasarımında yalnızca teorik kurallar değil, uygulamanın gerçek ihtiyaçları da dikkate alınmalıdır.
Denormalizasyon Nedir?
Denormalizasyon, performans veya raporlama gibi özel ihtiyaçlar nedeniyle bazı verilerin bilinçli olarak tekrar saklanmasıdır.
Örneğin çok büyük bir e-ticaret sisteminde sipariş toplamının her raporda yeniden hesaplanması maliyetli olabilir.
Teorik olarak toplam şu şekilde hesaplanabilir:
SELECT
SiparisId,
SUM(Adet * BirimFiyat) AS SiparisToplami
FROM SiparisDetaylari
GROUP BY SiparisId;
Ancak milyonlarca sipariş bulunan bir sistemde SiparisToplami alanının sipariş tablosunda ayrıca saklanması performans açısından tercih edilebilir.
Burada önemli nokta, veri tekrarının yanlışlıkla değil bilinçli bir tasarım kararı sonucunda oluşturulmasıdır.
Önce doğru ve normalleştirilmiş bir yapı kurulmalı, daha sonra ölçüm sonuçlarına göre gerçekten ihtiyaç varsa denormalizasyon düşünülmelidir.
Her Veritabanı 3NF Olmak Zorunda mı?
Teorik olarak her tabloyu mümkün olduğunca normalleştirmek iyi bir başlangıçtır. Ancak gerçek projelerde uygulamanın kullanım amacı da önemlidir.
Örneğin:
- Günlük işlemlerin yapıldığı OLTP sistemlerinde normalizasyon genellikle önemlidir.
- Raporlama sistemlerinde daha az normalize edilmiş tablolar tercih edilebilir.
- Veri ambarlarında yıldız şeması gibi farklı tasarım yöntemleri kullanılabilir.
- Çok büyük sistemlerde performans için bazı veriler tekrar saklanabilir.
Bu nedenle “normalizasyon her zaman daha fazla tablo oluşturmaktır” şeklinde düşünmek doğru değildir.
Asıl amaç, veriyi mantıklı ve yönetilebilir bir yapıda saklamaktır.
Sonuç
Normalizasyon, ilişkisel veritabanı tasarımının en önemli konularından biridir.
Doğru bir normalizasyon yapısı:
- Veri tekrarını azaltır.
- Güncelleme hatalarını önler.
- Veri bütünlüğünü artırır.
- Tablolar arasındaki ilişkileri daha anlaşılır hale getirir.
- Veritabanının bakımını kolaylaştırır.
Pratikte çoğu uygulama için 1NF, 2NF ve 3NF kurallarını doğru anlamak güçlü bir veritabanı tasarımı için yeterli bir temel oluşturur.
Ancak normalizasyonun temel amacı mümkün olduğunca fazla tablo oluşturmak değildir. Amaç, her verinin doğru yerde tutulmasını sağlamak ve veritabanını uzun vadede daha güvenli, tutarlı ve yönetilebilir hale getirmektir.
İyi tasarlanmış bir veritabanında her tablo belirli bir işi yapar, her veri mümkün olduğunca tek bir yerde tutulur ve tablolar arasındaki ilişkiler açık şekilde tanımlanır.
Kısacası normalizasyon, yalnızca teorik bir veritabanı konusu değil; gerçek projelerde veri kalitesini, bakım kolaylığını ve sistemin gelecekte büyüyebilmesini doğrudan etkileyen önemli bir tasarım yaklaşımıdır.
1 Yorumlar
deneme
Yporum buraya yazılsa da beni benden alan bi yorum olsa