Gereksinimler ve Ön Hazırlık
Bu rehberdeki uygulamaları gerçekleştirmek için sisteminizde güncel bir SQL veritabanı yönetim sistemi kurulu olmalıdır. 2026 yılı itibarıyla PostgreSQL 17+ veya MySQL 9.0+ sürümleri, modern JSONB desteği ve performans iyileştirmeleri nedeniyle önerilmektedir. Ayrıca, veritabanı şemanızı görselleştirmek için dbdiagram.io veya pgAdmin gibi araçları kullanmanız, tasarım aşamasında hataları erkenden fark etmenize yardımcı olacaktır.
- PostgreSQL veya MySQL veritabanı sunucusu.
- SQL komutlarını çalıştırmak için bir terminal veya GUI arayüzü (DBeaver, pgAdmin).
- Veri modelleme mantığını kavramak için temel SQL bilgisi.
Adım 1: Gereksinim Analizi ve Varlık-İlişki Modelleme (ERD)
Veritabanı tasarımı kod yazmadan başlar. İlk adım, uygulamanızdaki "varlıkları" (entities) ve bu varlıkların birbirleriyle olan ilişkilerini belirlemektir. Örneğin, bir e-ticaret uygulaması için "Kullanıcı", "Sipariş" ve "Ürün" temel varlıklardır.
İlişkileri belirlerken şu üç temel tipi kullanırız: One-to-One (Bire-Bir), One-to-Many (Bire-Çok) ve Many-to-Many (Çoka-Çok). Bu aşamada kağıt üzerinde veya bir modelleme aracıyla ERD (Entity Relationship Diagram) çizmek, karmaşıklığı azaltır.
Adım 2: Tablo Yapılarını Oluşturma ve Veri Tipleri
Tabloları oluştururken veri tipi seçimi, hem depolama alanı hem de sorgu performansı için hayati önem taşır. Gereksiz geniş veri tipleri (örneğin her sayı için BIGINT kullanmak) indeks boyutlarını şişirir.
-- Kullanıcılar tablosunun oluşturulması
CREATE TABLE kullanicilar (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
sifre_hash VARCHAR(255) NOT NULL,
olusturulma_tarihi TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
Yukarıdaki örnekte, UUID kullanarak benzersiz anahtarlar oluşturduk. Bu, veritabanı birleştirme senaryolarında çakışmaları önlemek için modern bir yaklaşımdır.
Adım 3: İlişkisel Bütünlüğü Sağlama (Foreign Keys)
Tablolar arasındaki bağlantıları FOREIGN KEY (Yabancı Anahtar) kısıtlamaları ile kurarız. Bu, veritabanı seviyesinde "referans bütünlüğü" sağlar. Örneğin, bir siparişin var olmayan bir kullanıcıya ait olmasını engellemek için bu kısıtlamalar zorunludur.
-- Siparişler tablosunun kullanıcılar ile ilişkilendirilmesi
CREATE TABLE siparisler (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
kullanici_id UUID REFERENCES kullanicilar(id) ON DELETE CASCADE,
toplam_tutar DECIMAL(12, 2) NOT NULL,
siparis_tarihi TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
ON DELETE CASCADE kuralı, bir kullanıcı silindiğinde ona ait siparişlerin de otomatik olarak temizlenmesini sağlar. Bu, veri tutarlılığını korumak için etkili bir yöntemdir.
Adım 4: Normalizasyon ve Veri Tekrarını Önleme
Normalizasyon, veritabanındaki veri tekrarını azaltma işlemidir. 1NF, 2NF ve 3NF kuralları, veriyi atomik parçalara bölerek güncelleme anomalilerini engeller. Örneğin, müşteri adreslerini "Kullanıcılar" tablosuna gömmek yerine ayrı bir "Adresler" tablosunda tutmak 3NF prensibine uygundur.
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| Normalizasyon (3NF) | Veri tekrarı yok, güncelleme kolay. | Çok sayıda JOIN işlemi performans düşürebilir. |
| Denormalizasyon | Hızlı okuma, az JOIN. | Veri tutarsızlığı riski, güncelleme maliyeti. |
Adım 5: İndeksleme ile Performans Optimizasyonu
Veritabanı şemanız ne kadar iyi olursa olsun, doğru indekslenmemiş tablolar büyük verilerde yavaş çalışır. Sık sorgulanan sütunlara (örneğin email, kullanıcı_id) indeks eklemek, sorgu süresini milisaniyelere indirir.
-- Email aramaları için B-Tree indeksi oluşturma
CREATE INDEX idx_kullanicilar_email ON kullanicilar(email);
-- Sipariş tarihine göre sıralama performansı için indeks
CREATE INDEX idx_siparisler_tarih ON siparisler(siparis_tarihi DESC);
Fazla indeks eklemek, veri ekleme (INSERT) işlemlerini yavaşlatır. Bu yüzden sadece ihtiyacınız olan sütunları indeksleyin.
Adım 6: Güvenlik ve Veri Gizliliği
Veritabanı güvenliği, sadece şifreleme ile sınırlı değildir. Uygulama seviyesinde SQL Injection saldırılarına karşı hazırlıklı olmalısınız. Ayrıca, hassas verileri (şifreler) asla düz metin olarak saklamayın; mutlaka güçlü hash algoritmaları (Argon2 veya BCrypt) kullanın.
Kritik Uyarı: Veritabanı şemanızı tasarlarken "Least Privilege" (En Az Yetki) prensibini uygulayın. Uygulamanızın veritabanı kullanıcısına, sadece ihtiyaç duyduğu tablolara erişim (SELECT, INSERT, UPDATE) yetkisi verin. Asla 'root' veya 'admin' yetkili kullanıcı ile uygulama bağlantısı kurmayın.
-- Güvenli bir kullanıcı oluşturma ve yetkilendirme örneği
CREATE USER uygulama_kullanicisi WITH PASSWORD 'guclu_bir_sifre_123';
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO uygulama_kullanicisi;
Sıkça Sorulan Sorular
UUID mi yoksa Serial (Integer) mı kullanmalıyım?
Dağıtık sistemlerde ve ölçeklenebilir uygulamalarda UUID, çakışma riski taşımadığı için tercih edilir. Ancak çok küçük ve performansa aşırı duyarlı sistemlerde Integer kullanımı bir miktar hız avantajı sağlayabilir.
JSONB sütunları ne zaman kullanılmalı?
PostgreSQL gibi sistemlerde JSONB, şemanın esnek olması gereken (örneğin ürün özellikleri gibi değişken veriler) durumlarda kullanılır. Ancak ana ilişkilerde mutlaka klasik tabloları tercih edin.
Normalizasyon her zaman gerekli mi?
Genellikle evet, ancak çok yüksek trafikli okuma odaklı sistemlerde performans için bazı tabloların denormalize edilmesi (birleştirilmesi) gerekebilir. Bu, tasarımın son aşamasında değerlendirilmelidir.
SQL Injection nasıl engellenir?
SQL Injection, doğrudan veritabanı şeması ile değil, uygulama kodundaki sorgu yazım şekliyle engellenir. Daima "Prepared Statements" (Hazırlanmış İfadeler) kullanarak parametreli sorgular çalıştırın.
Veritabanı şeması nasıl güncellenir?
Şemayı manuel değiştirmek yerine "Migration" (Göç) araçlarını kullanın. Bu araçlar, veritabanı değişikliklerini versiyon kontrol sistemiyle (Git) yönetmenizi sağlar.
İleri Düzey İpucu: Veritabanı Migration (Göç) Stratejileri
Veritabanı şemanızı oluşturduktan sonra, uygulama geliştikçe şemada değişiklik yapmanız kaçınılmazdır. Manuel olarak ALTER TABLE komutlarını çalıştırmak, özellikle ekip çalışmasında büyük hatalara ve tutarsızlıklara yol açar. Profesyonel projelerde "Migration" (Göç) dosyaları kullanarak veritabanı sürüm takibi yapmalısınız.
Bir migration dosyası, veritabanı şemasındaki her değişikliği bir zaman damgasıyla kayıt altına alır. Örneğin, bir kullanıcı tablosuna phone_number sütunu eklemek istediğinizde, bunu doğrudan veritabanı üzerinde değil, kod tabanınızdaki bir dosya ile yapmalısınız:
-- 20231027103000_add_phone_to_users.sql
BEGIN;
ALTER TABLE users
ADD COLUMN phone_number VARCHAR(20);
CREATE INDEX idx_users_phone ON users(phone_number);
COMMIT;
Bu yaklaşım, veritabanı yapınızın uygulamanızın kodlarıyla senkronize kalmasını sağlar. Eğer bir hata oluşursa, ROLLBACK mekanizması sayesinde veritabanını bir önceki kararlı haline saniyeler içinde geri döndürebilirsiniz.
Veritabanı Performansını İzleme: EXPLAIN ANALYZE Kullanımı
Şema tasarımınızın ne kadar verimli olduğunu anlamanın en iyi yolu, sorgularınızın veritabanı motoru tarafından nasıl işlendiğini görmektir. EXPLAIN ANALYZE komutu, sorgunuzun çalışma planını, hangi indekslerin kullanıldığını ve işlemin ne kadar sürdüğünü detaylı bir şekilde raporlar.
Aşağıdaki örnekte, bir sipariş tablosunda tarih bazlı arama yaparken indeksin kullanılıp kullanılmadığını nasıl kontrol edeceğinizi görebilirsiniz:
EXPLAIN ANALYZE
SELECT * FROM orders
WHERE created_at > '2023-01-01'
AND status = 'completed';
Bu komutu çalıştırdığınızda alacağınız çıktıda dikkat etmeniz gereken anahtar kelimeler şunlardır:
- Seq Scan (Sequential Scan): Veritabanının tüm tabloyu baştan sona taradığı anlamına gelir. Büyük tablolarda bu, performans kaybıdır ve ilgili sütuna indeks eklemeniz gerektiğini gösterir.
- Index Scan: Sorgunun indeks kullanarak hızlı bir şekilde veriye ulaştığını gösterir. İdeal olan budur.
- Cost: Sorgunun tahmini maliyetidir. Bu değerin düşük olması, sorgunun daha hızlı çalıştığını ifade eder.
Performans optimizasyonu yaparken sadece indeks eklemek yeterli değildir; gereksiz indeksler de yazma (INSERT/UPDATE) işlemlerini yavaşlatır. Bu nedenle, sadece sıkça filtreleme yaptığınız veya JOIN işlemlerinde kullandığınız sütunlara indeks tanımlamaya özen gösterin.
Profesyonel İpucu: Çok büyük tablolarda (milyonlarca satır)SELECT *kullanmak yerine, sadece ihtiyacınız olan sütunları seçmek (SELECT id, name) ağ trafiğini ve bellek kullanımını ciddi oranda azaltacaktır.
Sonuç
SQL & Veritabanı ile uygulamalar için veri ilişkisel şema tasarımı, bir uygulamanın uzun vadeli başarısının temelidir. Adım adım ERD modellemesi yapmak, normalizasyon kurallarına uymak ve doğru indeksleme stratejileriyle çalışmak, uygulamanızın 2026 standartlarında yüksek performanslı olmasını sağlar. Bir sonraki adım olarak, veritabanı performansını izlemek için 'EXPLAIN ANALYZE' komutlarını öğrenerek sorgularınızın nasıl çalıştığını derinlemesine analiz etmeye başlayabilirsiniz.
Yasal Uyarı: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce mutlaka güvenlik testlerinden geçirin ve veritabanı yedekleme stratejilerinizi oluşturun.


Yorumlar (0)
Yorum Yaz