Veri Modelleme ve Veritabanı Tasarımı

Veri Modelleme ve Veritabanı Tasarımı, iş süreçlerini desteklemek ve verimli veri yönetimi sağlamak amacıyla verilerin yapısını, ilişkilerini ve kısıtlamalarını tanımlayan bir süreçtir. Kavramsal, mantıksal ve fiziksel modeller aracılığıyla veritabanı şemaları oluşturulur; ER diyagramları, UML ve DDD gibi yaklaşımlar kullanılarak iş mantığı modellenir. Normalizasyon, veri bütünlüğünü korurken, indeksleme ve denormalizasyon performansı optimize eder. Şema versiyonlama ve kısıtlamalar, büyük ölçekli sistemlerde sürdürülebilirliği sağlar.

Veri Modelleme Temelleri
Veri modelinin amacı ve önemi

Veri modeli, bir organizasyonun verilerinin yapısını, ilişkilerini ve kısıtlamalarını tanımlayan bir çerçevedir. Temel amaçları şunlardır:

  • Veri Yapısını Anlaşılır Kılmak: Verilerin nasıl organize edildiğini ve birbirleriyle nasıl ilişkili olduğunu görselleştirir.
  • Veri Tutarlılığını Sağlamak: Farklı sistemler ve ekipler arasında standart bir veri tanımı sunar.
  • Veri Yönetimini Kolaylaştırmak: Veri tabanı tasarımı, veri entegrasyonu ve analitik süreçler için temel oluşturur.
  • İş Gereksinimlerini Desteklemek: İş süreçlerini optimize etmek için verilerin doğru ve etkili bir şekilde kullanılmasını sağlar.
İş Süreçlerine Katkıları

Veri modelleri, iş süreçlerini aşağıdaki yollarla destekler:

  1. Veri Erişimini Hızlandırır: İyi tasarlanmış bir veri modeli, veri sorgularını optimize ederek analitik ve raporlama süreçlerini hızlandırır. Örneğin, bir perakende şirketi, stok verilerini hızlıca analiz ederek tedarik zinciri kararlarını iyileştirebilir.
  2. Veri Kalitesini Artırır: Standartlaştırılmış veri tanımları, veri giriş hatalarını azaltır ve tutarlılık sağlar. Örneğin, bir hastanede hasta kayıtlarının doğru modellenmesi, yanlış tedavilerin önüne geçer.
  3. Sistem Entegrasyonunu Kolaylaştırır: Farklı sistemler arasında veri akışını düzenler. Örneğin, bir CRM ve ERP sistemi arasında veri modeli, müşteri verilerinin sorunsuz paylaşımını sağlar.
  4. Stratejik Karar Alma: Veri modelleri, iş zekası araçlarının doğru verilere erişmesini sağlayarak stratejik kararları destekler. Örneğin, bir banka, kredi risk analizini veri modeli üzerinden gerçekleştirir.

Gerçek Dünya Örneği: Amazon, ürün kataloglarını, müşteri verilerini ve sipariş geçmişini yönetmek için karmaşık veri modelleri kullanır. Bu modeller, öneri sistemlerini güçlendirir ve lojistik süreçlerini optimize ederek müşteri memnuniyetini artırır.

Veri Modellemede En Sık Yapılan Hatalar

İş Gereksinimlerini Göz Ardı Etme:

  • Hata: Model, iş ihtiyaçlarını değil, yalnızca teknik gereksinimleri karşılar.
  • Örnek: Bir e-ticaret platformu, müşteri segmentasyonunu desteklemeyen bir veri modeli kullanırsa, pazarlama kampanyaları etkisiz kalır.
  • Çözüm: İş paydaşlarıyla yakın iş birliği yaparak gereksinimleri netleştirmek.

Aşırı Karmaşık veya Yetersiz Model Tasarımı:

  • Hata: Gereksiz detaylarla karmaşıklaşan veya çok basit modeller, performansı düşürür.
  • Örnek: Bir sigorta şirketi, tüm müşteri verilerini tek bir tabloda toplamaya çalışırsa, sorgular yavaşlar ve bakım zorlaşır.
  • Çözüm: Normalizasyon ve denormalizasyon dengesini iyi kurmak.

Veri İlişkilerini Yanlış Tanımlama:

  • Hata: Yanlış anahtar ilişkileri veya eksik kısıtlamalar, veri tutarsızlığına yol açar.
  • Örnek: Bir okul yönetim sisteminde öğrenci ve ders ilişkileri yanlış tanımlanırsa, bir öğrenci yanlış sınıfa atanabilir.
  • Çözüm: İlişkisel veri tabanı ilkelerine (ör. foreign key) bağlı kalmak.

Gelecek İhtiyaçlarını Düşünmeme:

  • Hata: Model, mevcut ihtiyaçlara odaklanır ve ölçeklenebilirlik göz ardı edilir.
  • Örnek: Bir startup, başlangıçta basit bir veri modeli kullanır, ancak büyüdükçe yeni veri türlerini destekleyemez.
  • Çözüm: Esnek ve modüler bir tasarım benimsemek.

Dökümantasyon Eksikliği:

  • Hata: Modelin amacı ve yapısı belgelenmez, bu da bakım ve geliştirme süreçlerini zorlaştırır.
  • Örnek: Bir finans şirketinde veri modelinin dökümantasyonu eksikse, yeni bir geliştirici sistemi anlamakta zorlanır.
  • Çözüm: Veri sözlüğü ve şema dökümantasyonu oluşturmak.
Gerçek Dünya Örnekleri
  • Hata Örneği (Uber): Uber’in erken dönemlerinde, veri modeli yerel pazar ihtiyaçlarını tam desteklemiyordu. Örneğin, bazı şehirlerdeki ödeme sistemleri için ek alanlar gerekiyordu, ancak model bu esnekliği sağlamıyordu. Bu, yeni özelliklerin entegrasyonunu yavaşlattı. Uber, modeli modüler hale getirerek bu sorunu çözdü.
  • Başarı Örneği (Netflix): Netflix’in veri modeli, kullanıcı davranışlarını (izleme geçmişi, beğeniler) ve içerik metadatalarını etkili bir şekilde ilişkilendirir. Bu, kişiselleştirilmiş öneriler sunarak kullanıcı deneyimini güçlendirir ve iş süreçlerini optimize eder.
Kavramsal, mantıksal ve fiziksel veri modelleri arasındaki farklar
1. Kavramsal Veri Modeli

Tanım: Kavramsal veri modeli, verilerin iş açısından yüksek seviyeli bir temsilini sağlar. İş süreçlerini ve temel veri varlıklarını (entities) tanımlar, ancak teknik detaylara girmez.

Özellikler:

  • İş odaklıdır ve teknik detaylardan bağımsızdır.
  • Genellikle varlık-ilişki diyagramları (ERD) kullanılarak temsil edilir.
  • Varlıklar (ör. Müşteri, Sipariş) ve aralarındaki ilişkiler (ör. Müşteri Sipariş Verir) tanımlanır.
  • Veritabanı teknolojisinden bağımsızdır.

Örnek: Bir e-ticaret sistemi için kavramsal model, “Müşteri”, “Ürün” ve “Sipariş” gibi varlıkları ve bunların ilişkilerini (ör. Müşteri Sipariş Verir) içerir.

Dikkat Edilmesi Gerekenler:

  • İş Gereksinimlerinin Netliği: İş paydaşlarıyla yakın iş birliği yapılarak gereksinimler doğru anlaşılmalıdır.
  • Basitlik: Model, gereksiz detaylardan arındırılmış ve anlaşılır olmalıdır.
  • Tam Kapsayıcılık: Tüm temel iş varlıkları ve ilişkileri tanımlanmalıdır.
  • Esneklik: Gelecekteki iş ihtiyaçlarını destekleyecek şekilde tasarlanmalıdır.

2. Mantıksal Veri Modeli

Tanım: Mantıksal veri modeli, kavramsal modelin daha ayrıntılı bir versiyonudur. Verilerin yapısını, ilişkilerini ve kısıtlamalarını tanımlar, ancak hala fiziksel depolama detaylarından bağımsızdır.

Özellikler:

  • Varlıkların öznitelikleri (attributes) (ör. Müşteri: Ad, Soyad, E-posta) tanımlanır.
  • Birincil ve yabancı anahtarlar (primary/foreign keys) gibi ilişkisel yapılar belirtilir.
  • Normalizasyon kuralları uygulanır (ör. 1NF, 2NF, 3NF).
  • Veritabanı yönetim sistemi (DBMS) bağımsızdır.

Örnek: E-ticaret örneğinde, mantıksal model, Müşteri tablosunda “MüşteriID (PK)”, “Ad”, “Soyad” gibi öznitelikleri ve Sipariş tablosuyla ilişkisini (ör. MüşteriID foreign key) içerir.

Dikkat Edilmesi Gerekenler:

  • Normalizasyon: Verinin tekrarını önlemek ve tutarlılığı sağlamak için normalizasyon doğru uygulanmalıdır.
  • Veri Bütünlüğü: Anahtarlar ve kısıtlamalar (ör. NOT NULL, UNIQUE) doğru tanımlanmalıdır.
  • İlişkilerin Doğruluğu: Varlıklar arasındaki ilişkiler (1:1, 1:N, N:N) doğru modellenmelidir.
  • Performans Dengesi: Aşırı normalizasyon, performans sorunlarına yol açabilir; bu nedenle iş ihtiyaçlarına uygun bir denge kurulmalıdır.

3. Fiziksel Veri Modeli

Tanım: Fiziksel veri modeli, mantıksal modelin belirli bir veritabanı teknolojisine (ör. MySQL, Oracle) uyarlanmış halidir. Verilerin nasıl depolanacağını, indeksleneceğini ve optimize edileceğini tanımlar.

Özellikler:

  • Tablo yapıları, sütun veri türleri (ör. VARCHAR, INT) ve indeksler tanımlanır.
  • Depolama detayları (ör. partition, tablespace) belirtilir.
  • Performans optimizasyonları (ör. indeksler, denormalizasyon) uygulanır.
  • Veritabanı teknolojisine özgü özellikler kullanılır.

Örnek: E-ticaret örneğinde, fiziksel model, Müşteri tablosunda “MüşteriID INT PRIMARY KEY”, “Ad VARCHAR(50)” gibi sütunlar ve performans için indeksler içerir.

Dikkat Edilmesi Gerekenler:

  • Performans Optimizasyonu: Sık kullanılan sorgular için indeksler ve uygun veri türleri seçilmelidir.
  • Depolama Kısıtlamaları: Veritabanı sisteminin depolama kapasitesi ve sınırlamaları dikkate alınmalıdır.
  • Güvenlik: Veri erişim kontrolleri ve şifreleme gibi güvenlik önlemleri tanımlanmalıdır.
  • Bakım Kolaylığı: Model, gelecekteki güncellemeler ve bakım için esnek olmalıdır.

Modeller Arasındaki Dönüşüm Süreçleri

Veri modelleme, genellikle kavramsal modelden başlayarak mantıksal ve fiziksel modellere doğru ilerleyen bir süreçtir. Dönüşüm süreçleri şöyledir:

Kavramsaldan Mantıksala Dönüşüm:

  • Adımlar:
    • Kavramsal modeldeki varlıklar, mantıksal modelde tablolara dönüştürülür.
    • Varlıkların öznitelikleri tanımlanır (ör. Müşteri için Ad, Soyad).
    • İlişkiler, birincil ve yabancı anahtarlarla ifade edilir.
    • Normalizasyon uygulanarak veri tekrarı önlenir.
  • Kritik Noktalar:
    • İş gereksinimlerinin tam olarak yansıtıldığından emin olun.
    • İlişkilerin doğru tanımlandığını kontrol edin (ör. 1:N ilişkisi için yabancı anahtar).
    • Gereksiz özniteliklerden kaçının.
  • Örnek: Kavramsal modelde “Müşteri Sipariş Verir” ilişkisi, mantıksal modelde Sipariş tablosunda “MüşteriID” yabancı anahtarı olarak tanımlanır.

Mantıksaldan Fiziksele Dönüşüm:

  • Adımlar:
    • Mantıksal modeldeki tablolar, belirli bir DBMS’ye uygun fiziksel tablolara dönüştürülür.
    • Öznitelikler için veri türleri (ör. VARCHAR, INT) ve kısıtlamalar belirlenir.
    • Performans için indeksler, partition’lar veya denormalizasyon uygulanır.
    • Depolama yapıları (ör. tablespace) ve güvenlik ayarları tanımlanır.
  • Kritik Noktalar:
    • DBMS’nin özelliklerine ve sınırlamalarına uygun tasarım yapılmalıdır.
    • Performans testleri yapılarak sorgu hızı optimize edilmelidir.
    • Gelecekteki ölçeklendirme ihtiyaçları göz önünde bulundurulmalıdır.
  • Örnek: Mantıksal modeldeki “Ad” özniteliği, fiziksel modelde “VARCHAR(50) NOT NULL” olarak tanımlanır ve sık sorgulanıyorsa indeks eklenir.

Genel Kritik Noktalar
  • Paydaş İş Birliği: Her aşamada iş paydaşları, veri mimarları ve geliştiriciler arasında iletişim sağlanmalıdır.
  • Dökümantasyon: Her modelin amacı, yapısı ve kararları belgelenmelidir.
  • Esneklik ve Ölçeklenebilirlik: Modeller, gelecekteki iş ihtiyaçlarını ve veri hacmi artışını desteklemelidir.
  • Test ve Doğrulama: Her aşamada modelin doğruluğu ve performansı test edilmelidir.

Gerçek Dünya Örneği

Amazon’un Veri Modelleme Süreci:

  • Kavramsal Model: Amazon, müşteri, ürün ve sipariş gibi temel varlıkları tanımlayarak iş süreçlerini (ör. satın alma, öneri sistemi) modeller.
  • Mantıksal Model: Bu varlıklar, öznitelikler (ör. Ürün: Fiyat, Kategori) ve ilişkilerle (ör. Müşteri-Ürün ilişkisi) detaylandırılır. Normalizasyon uygulanır.
  • Fiziksel Model: Amazon’un kullandığı DynamoDB gibi NoSQL veritabanına uygun tablo yapıları ve indeksler tanımlanır. Örneğin, ürün aramaları için ikincil indeksler eklenir.

Hata Örneği: Bir sağlık kuruluşu, kavramsal modelde hasta ve tedavi ilişkisini eksik tanımlarsa, mantıksal modelde yanlış anahtar ilişkileri oluşabilir. Bu, fiziksel modelde veri tutarsızlığına yol açar (ör. bir hastanın yanlış tedaviye atanması).

Veri modelleme notasyonları (ER, UML, IDEF1X)
1. ER (Entity-Relationship) Notasyonu

Tanım: ER notasyonu, varlık-ilişki diyagramları (ERD) ile veri modellerini temsil eder. Varlıklar (entities), öznitelikler (attributes) ve ilişkiler (relationships) temel bileşenlerdir.

Avantajları:

  • Basitlik ve Anlaşılırlık: ER diyagramları, hem teknik hem de iş paydaşları için kolayca anlaşılır.
  • Veritabanı Tasarımına Odaklanma: İlişkisel veritabanı tasarımı için özel olarak geliştirilmiştir.
  • Standartlaşma: Yaygın kullanımı sayesinde birçok veritabanı tasarım aracı tarafından desteklenir (ör. MySQL Workbench, ERwin).
  • Esneklik: Hem kavramsal hem de mantıksal modelleme için kullanılabilir.

Dezavantajları:

  • Sınırlı Kapsam: Nesne yönelimli sistemler veya karmaşık iş mantığı için yetersiz kalabilir.
  • Standartlaşma Eksikliği: Farklı araçlar ve uygulayıcılar arasında notasyon varyasyonları olabilir (ör. Chen vs. Crow’s Foot).
  • Karmaşık Sistemlerde Yetersizlik: Büyük ve karmaşık sistemlerde detaylı süreç modellemesi için ek notasyonlar gerekebilir.

Uygun Olduğu Projeler:

  • İlişkisel Veritabanı Tasarımı: Küçük ve orta ölçekli veritabanı projelerinde (ör. bir e-ticaret platformunun müşteri, ürün ve sipariş verilerini modelleme).
  • Basit İş Süreçleri: İş paydaşlarının teknik bilgiye ihtiyaç duymadan veri yapısını anlaması gereken projelerde.
  • Örnek: Bir perakende şirketi, stok yönetimi için Müşteri, Ürün ve Sipariş varlıklarını modellemek için ER notasyonunu kullanabilir. Crow’s Foot notasyonu ile 1:N ilişkileri (ör. bir müşteri birden çok sipariş verebilir) kolayca gösterilir.

2. UML (Unified Modeling Language) Notasyonu

Tanım: UML, yazılım sistemlerini modellemek için standart bir dil sunar. Veri modellemesi için genellikle sınıf diyagramları (class diagrams) kullanılır, ancak diğer diyagram türleri (ör. use case, sequence) ile sistem tasarımı da desteklenir.

Avantajları:

  • Kapsayıcılık: Veri modellemenin ötesinde, sistem davranışlarını ve süreçlerini (ör. use case, sequence diagrams) modelleyebilir.
  • Nesne Yönelimli Tasarım: Sınıf diyagramları, nesne yönelimli programlama (OOP) ile uyumludur ve kalıtım, polimorfizm gibi kavramları destekler.
  • Standartlaşma: OMG (Object Management Group) tarafından standartlaştırılmıştır, bu nedenle tutarlı bir kullanım sağlar.
  • Geniş Araç Desteği: Enterprise Architect, Visual Paradigm gibi araçlarla yaygın desteklenir.

Dezavantajları:

  • Karmaşıklık: UML’nin geniş kapsamı, öğrenme eğrisini artırabilir ve basit projelerde gereksiz yere karmaşık gelebilir.
  • Veritabanı Odaklı Olmaması: İlişkisel veritabanı tasarımı için ER notasyonu kadar özel değildir; fiziksel modellemeye geçişte ek çaba gerekebilir.
  • İş Paydaşları için Zorluk: Teknik olmayan paydaşlar için sınıf diyagramları anlaşılması zor olabilir.

Uygun Olduğu Projeler:

  • Nesne Yönelimli Yazılım Geliştirme: Yazılım sistemlerinin hem veri hem de davranışlarını modellemek için (ör. bir bankacılık uygulamasında hesap yönetimi).
  • Karmaşık Sistemler: Çoklu modüller ve süreçler içeren projelerde (ör. bir ERP sistemi).
  • Örnek: Bir bankacılık uygulamasında, UML sınıf diyagramları ile “Hesap” ve “Müşteri” sınıfları, kalıtım (ör. Bireysel Hesap, Kurumsal Hesap) ve metodlar (ör. paraYatir()) modellenebilir. UML’nin sequence diyagramları, para transferi sürecini görselleştirebilir.

3. IDEF1X Notasyonu

Tanım: IDEF1X, veri modellemesi için özel olarak tasarlanmış bir notasyondur ve özellikle kurumsal veri yönetimi ve entegrasyon projelerinde kullanılır. Varlık-ilişki modellemesine dayanır, ancak daha katı kuralları vardır.

Avantajları:

  • Detaylı ve Kesin Kurallar: IDEF1X, veri bütünlüğü ve ilişkisel tasarım için kesin standartlar sunar (ör. bağımlı/bağımsız varlıklar).
  • Kurumsal Veri Yönetimi: Büyük ölçekli ve karmaşık veri entegrasyon projelerine uygun.
  • Normalizasyon Desteği: Veritabanı normalizasyon kurallarını (1NF, 2NF, 3NF) destekler ve veri tutarlılığını sağlar.
  • Resmi Dökümantasyon: Devlet ve savunma projelerinde sıkça kullanılan resmi bir standarttır.

Dezavantajları:

  • Karmaşıklık: Katı kuralları ve terminolojisi, öğrenmeyi ve uygulamayı zorlaştırabilir.
  • Sınırlı Kullanım Alanı: Nesne yönelimli sistemler veya süreç modellemesi için uygun değildir.
  • Erişim Zorluğu: ER ve UML kadar yaygın araç desteği yoktur; özel araçlar gerekebilir.
  • İş Paydaşları için Anlaşılmazlık: Teknik olmayan kullanıcılar için fazla karmaşık olabilir.

Uygun Olduğu Projeler:

  • Kurumsal Veri Entegrasyonu: Farklı sistemler arasında veri tutarlılığı gerektiren projelerde (ör. bir hükümet veri tabanı).
  • Büyük Ölçekli Veritabanları: Yüksek veri bütünlüğü gerektiren projelerde (ör. bir sigorta şirketinin müşteri ve poliçe verileri).
  • Örnek: Bir sigorta şirketi, müşteri, poliçe ve talep verilerini entegre etmek için IDEF1X kullanabilir. IDEF1X’in bağımlı varlık tanımları, bir talebin mutlaka bir poliçeye bağlı olmasını garanti eder.

Karşılaştırmalı Analiz Tablosu
KriterER NotasyonuUML NotasyonuIDEF1X Notasyonu
Amaçİlişkisel veritabanı tasarımıYazılım sistemi ve nesne yönelimli modellemeKurumsal veri modelleme ve entegrasyon
KapsamVarlık-ilişki odaklıVeri, süreç ve davranış modellemeDetaylı veri modelleme
KolaylıkBasit ve anlaşılırOrta derecede karmaşıkKarmaşık ve teknik
StandartlaşmaKısmen standart (varyasyonlar var)Yüksek (OMG standardı)Yüksek (resmi standart)
Araç DesteğiGeniş (MySQL Workbench, ERwin)Geniş (Enterprise Architect, Visio)Sınırlı (özel araçlar)
İş Paydaşları için UygunlukYüksekOrtaDüşük
Normalizasyon DesteğiOrtaDüşükYüksek
Nesne Yönelimli DestekYokYüksekYok

Hangi Notasyon Hangi Projede Uygun?

ER Notasyonu:

  • Uygun Olduğu Durumlar:
    • Küçük ve orta ölçekli ilişkisel veritabanı projeleri.
    • İş paydaşlarının veri modelini anlaması gereken projeler.
    • Hızlı prototipleme ve kavramsal modelleme.
  • Örnek: Bir restoran zinciri, sipariş ve rezervasyon sistemini tasarlamak için ER notasyonunu kullanabilir. Müşteri, Sipariş ve Menü varlıkları arasındaki ilişkiler basitçe modellenir.
  • Neden Uygun?: Basitliği ve ilişkisel veritabanı tasarımına odaklanması, hızlı geliştirme ve iş paydaşlarıyla iletişimi kolaylaştırır.

UML Notasyonu:

  • Uygun Olduğu Durumlar:
    • Nesne yönelimli yazılım geliştirme projeleri.
    • Veri modellemenin yanı sıra süreç ve davranış modellemesi gereken projeler.
    • Karmaşık sistemler ve modüler tasarımlar.
  • Örnek: Bir sağlık uygulaması, hasta kayıtlarını (sınıf diyagramı), doktor randevu süreçlerini (sequence diyagramı) ve kullanıcı rollerini (use case diyagramı) modellemek için UML kullanabilir.
  • Neden Uygun?: UML’nin geniş kapsamı, hem veri hem de sistem davranışlarını modellemeyi mümkün kılar ve nesne yönelimli sistemlerle uyumludur.

IDEF1X Notasyonu:

  • Uygun Olduğu Durumlar:
    • Büyük ölçekli kurumsal veri entegrasyon projeleri.
    • Yüksek veri bütünlüğü ve normalizasyon gerektiren sistemler.
    • Resmi standartların zorunlu olduğu projeler (ör. devlet, savunma).
  • Örnek: Bir hükümet kurumu, vatandaş verilerini (nüfus, vergi, sosyal güvenlik) entegre etmek için IDEF1X kullanabilir. Bağımlı varlık tanımları, veri tutarlılığını sağlar.
  • Neden Uygun?: IDEF1X’in katı kuralları, karmaşık ve kritik veri sistemlerinde tutarlılık ve doğruluk sağlar.

Gerçek Dünya Örnekleri
  • ER Kullanımı (Amazon): Amazon’un erken dönemlerinde, ürün kataloğu ve müşteri verilerini modellemek için ER notasyonu kullanıldı. Basitliği sayesinde hızlı prototipleme yapıldı ve iş paydaşları veri yapısını kolayca anladı.
  • UML Kullanımı (Netflix): Netflix, öneri sistemini ve kullanıcı arayüzünü tasarlamak için UML sınıf ve sequence diyagramlarını kullandı. Nesne yönelimli tasarımı, sistemin modülerliğini ve ölçeklenebilirliğini artırdı.
  • IDEF1X Kullanımı (ABD Savunma Bakanlığı): ABD Savunma Bakanlığı, lojistik ve personel verilerini entegre etmek için IDEF1X’i tercih etti. Katı kuralları, farklı sistemler arasında veri tutarlılığını sağladı.
İlişkisel Veritabanı Konseptleri
Tablolar, satırlar ve sütunlar
1. Temel Bileşenler
a. Tablolar (Tables)
  • Tanım: Verilerin organize edildiği temel yapıdır. Her tablo, belirli bir varlık türünü (ör. Müşteri, Sipariş) temsil eder.
  • Özellikler: Tablolar, satır ve sütunlardan oluşur. Her tablo benzersiz bir isme sahiptir ve belirli bir şemaya göre tanımlanır.
  • Örnek: Bir e-ticaret sisteminde Musteriler ve Siparisler tabloları.
b. Satırlar (Rows)
  • Tanım: Bir tabloda tek bir veri kaydını temsil eder. Her satır, tablonun temsil ettiği varlığın bir örneğidir.
  • Özellikler: Satırlar, tablonun sütunlarına karşılık gelen değerler içerir. Bir tablodaki her satır benzersiz olmalıdır (genellikle birincil anahtar ile).
  • Örnek: Musteriler tablosunda bir satır, belirli bir müşterinin bilgilerini (ör. ID, ad, e-posta) içerir.
c. Sütunlar (Columns)
  • Tanım: Tablodaki her satırda saklanan veri türlerini tanımlar. Her sütun, belirli bir özniteliği (attribute) temsil eder.
  • Özellikler: Sütunlar, veri tipi (ör. INT, VARCHAR) ve kısıtlamalar (ör. NOT NULL) ile tanımlanır.
  • Örnek: Musteriler tablosunda sütunlar: MusteriID, Ad, Eposta.

2. Bileşenler Arasındaki İlişkiler

İlişkisel veritabanlarında tablolar, birincil anahtarlar (primary keys) ve yabancı anahtarlar (foreign keys) aracılığıyla birbirine bağlanır. Bu ilişkiler, veri bütünlüğünü sağlar ve veriler arasında anlamlı bağlantılar kurar.

a. Birincil Anahtar (Primary Key)
  • Tanım: Bir tablodaki her satırı benzersiz şekilde tanımlayan bir sütun veya sütun kombinasyonudur.
  • Özellikler: Tekrar eden veya NULL değerler içeremez.
  • Örnek: Musteriler tablosunda MusteriID birincil anahtar olabilir.
b. Yabancı Anahtar (Foreign Key)
  • Tanım: Bir tablodaki bir sütun, başka bir tablonun birincil anahtarına referans verir. Bu, tablolar arasında ilişki kurar.
  • Özellikler: Yabancı anahtar, referans aldığı tablonun birincil anahtarında bulunan bir değere sahip olmalıdır.
  • Örnek: Siparisler tablosundaki MusteriID, Musteriler tablosunun MusteriID sütununa referans veren bir yabancı anahtardır.
c. İlişki Türleri
  • 1:1 (Bire Bir): Bir tablodaki bir satır, diğer tablodaki yalnızca bir satırla ilişkilidir. Ör. Bir müşterinin tek bir pasaport kaydı.
  • 1:N (Bire Çok): Bir tablodaki bir satır, diğer tablodaki birden çok satırla ilişkilidir. Ör. Bir müşteri birden çok sipariş verebilir.
  • N:N (Çoka Çok): İki tablodaki satırlar birbirleriyle çoklu ilişkiler kurar. Bu, bir ara tablo (junction table) ile modellenir. Ör. Öğrenciler ve dersler arasındaki ilişki.

3. SQL Örnekleri

Bir e-ticaret veritabanı örneği üzerinden temel bileşenler ve ilişkiler SQL ile gösterilmiştir.

a. Tabloları Oluşturma
-- Musteriler tablosu
CREATE TABLE Musteriler (
    MusteriID INT PRIMARY KEY,
    Ad VARCHAR(50) NOT NULL,
    Soyad VARCHAR(50) NOT NULL,
    Eposta VARCHAR(100) UNIQUE
);

-- Siparisler tablosu
CREATE TABLE Siparisler (
    SiparisID INT PRIMARY KEY,
    MusteriID INT,
    SiparisTarihi DATE NOT NULL,
    ToplamTutar DECIMAL(10, 2),
    FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID)
);
  • Açıklama:
  • Musteriler tablosunda MusteriID birincil anahtar.
  • Siparisler tablosunda MusteriID, Musteriler tablosuna yabancı anahtar olarak bağlanıyor (1:N ilişki).
b. Veri Ekleme
-- Musteriler tablosuna veri ekleme
INSERT INTO Musteriler (MusteriID, Ad, Soyad, Eposta)
VALUES (1, 'Ahmet', 'Yılmaz', 'ahmet@example.com'),
       (2, 'Ayşe', 'Kaya', 'ayse@example.com');

-- Siparisler tablosuna veri ekleme
INSERT INTO Siparisler (SiparisID, MusteriID, SiparisTarihi, ToplamTutar)
VALUES (101, 1, '2025-05-01', 150.50),
       (102, 1, '2025-05-03', 89.90),
       (103, 2, '2025-05-04', 200.00);
  • Açıklama: Siparisler tablosuna eklenen her satır, Musteriler tablosunda var olan bir MusteriID’ye referans verir.
c. Veri Sorgulama (İlişkisel Sorgu)
-- Müşterilerin siparişleriyle birlikte listelenmesi (JOIN)
SELECT M.Ad, M.Soyad, S.SiparisID, S.SiparisTarihi, S.ToplamTutar
FROM Musteriler M
JOIN Siparisler S ON M.MusteriID = S.MusteriID;
  • Çıktı Örneği:
Ad      Soyad    SiparisID  SiparisTarihi  ToplamTutar
Ahmet   Yılmaz   101        2025-05-01     150.50
Ahmet   Yılmaz   102        2025-05-03     89.90
Ayşe    Kaya     103        2025-05-04     200.00
  • Açıklama: JOIN komutu, Musteriler ve Siparisler tablolarını MusteriID üzerinden birleştirir.
d. N:N İlişki Örneği

Öğrenciler ve dersler arasındaki çoka çok ilişkiyi modellemek için bir ara tablo kullanılır:

-- Ogrenciler tablosu
CREATE TABLE Ogrenciler (
    OgrenciID INT PRIMARY KEY,
    Ad VARCHAR(50) NOT NULL
);

-- Dersler tablosu
CREATE TABLE Dersler (
    DersID INT PRIMARY KEY,
    DersAdi VARCHAR(50) NOT NULL
);

-- Ara tablo (Ogrenci_Ders)
CREATE TABLE Ogrenci_Ders (
    OgrenciID INT,
    DersID INT,
    PRIMARY KEY (OgrenciID, DersID),
    FOREIGN KEY (OgrenciID) REFERENCES Ogrenciler(OgrenciID),
    FOREIGN KEY (DersID) REFERENCES Dersler(DersID)
);

-- Veri ekleme
INSERT INTO Ogrenciler (OgrenciID, Ad) VALUES (1, 'Ali'), (2, 'Zeynep');
INSERT INTO Dersler (DersID, DersAdi) VALUES (101, 'Matematik'), (102, 'Fizik');
INSERT INTO Ogrenci_Ders (OgrenciID, DersID) VALUES (1, 101), (1, 102), (2, 101);

-- Sorgu: Öğrencilerin aldığı dersler
SELECT O.Ad, D.DersAdi
FROM Ogrenciler O
JOIN Ogrenci_Ders OD ON O.OgrenciID = OD.OgrenciID
JOIN Dersler D ON OD.DersID = D.DersID;
  • Çıktı Örneği:
Ad      DersAdi
Ali     Matematik
Ali     Fizik
Zeynep  Matematik
  • Açıklama: Ogrenci_Ders ara tablosu, N:N ilişkisini yönetir. Her öğrenci birden çok derse, her ders birden çok öğrenciye bağlanabilir.

4. Önemli Noktalar
  • Veri Bütünlüğü: Yabancı anahtarlar, referans alınan tablodaki geçerli değerlere işaret etmelidir. Örneğin, Siparisler tablosuna MusteriID=999 eklenemez, çünkü Musteriler tablosunda böyle bir ID yoktur.
  • Normalizasyon: Tablolar, veri tekrarını önlemek için normalize edilmelidir (ör. 1NF, 2NF, 3NF).
  • Performans: Sık sorgulanan sütunlara indeks eklenerek sorgu performansı artırılabilir.
  • Kısıtlamalar: NOT NULL, UNIQUE ve CHECK gibi kısıtlamalar veri tutarlılığını sağlar.

Gerçek Dünya Örneği

Bir online kitapçı sisteminde:

  • Tablolar: Kitaplar (KitapID, Başlık, Yazar), Musteriler (MusteriID, Ad, Eposta), Siparisler (SiparisID, MusteriID, KitapID, Tarih).
  • İlişkiler:
  • Musteriler ve Siparisler arasında 1:N (bir müşteri birden çok sipariş verebilir).
  • Kitaplar ve Siparisler arasında 1:N (bir kitap birden çok siparişte yer alabilir).
  • SQL Kullanımı: Yukarıdaki JOIN sorgusu, hangi müşterinin hangi kitabı sipariş ettiğini gösterir.
Birincil anahtarlar, Yabancı anahtarlar ve Benzersiz tanımlayıcılar
1. Birincil Anahtarlar (Primary Key)

Rolü:

  • Benzersiz Tanımlama: Bir tablodaki her satırı (kayıt) benzersiz şekilde tanımlar.
  • Veri Bütünlüğü: Aynı tablodaki satırların tekrar etmesini önler ve NULL değerleri engeller.
  • İlişkisel Bağlantı: Yabancı anahtarlar aracılığıyla diğer tablolarla ilişki kurmak için referans noktasıdır.

Doğru Kullanım Stratejileri:

  • Benzersiz ve Anlamlı Seçim: Birincil anahtar, doğal bir benzersiz tanımlayıcı (ör. TC Kimlik No) veya yapay bir kimlik (ör. otomatik artan ID) olabilir. Yapay kimlikler genellikle daha esnek ve güvenlidir.
  • Kısa ve Basit Tutma: Performans için birincil anahtar mümkünse tek bir sütun olmalı ve veri tipi (ör. INT) hızlı sorgulamaya uygun olmalıdır.
  • Otomatik Artan Değerler: AUTO_INCREMENT gibi özellikler, benzersiz ID’lerin otomatik oluşturulmasını sağlar.
  • Değişmezlik: Birincil anahtar değerleri asla değiştirilmemelidir, çünkü bu diğer tablolardaki yabancı anahtarları etkileyebilir.

SQL Örneği:

CREATE TABLE Musteriler (
    MusteriID INT PRIMARY KEY AUTO_INCREMENT,
    Ad VARCHAR(50) NOT NULL,
    Eposta VARCHAR(100)
);

Yaygın Hatalar ve Kaçınma Yolları:

  • Hata: Anlamsız veya Değişken Değerler Kullanma: Örneğin, Ad gibi sık değişebilen bir sütunu birincil anahtar yapmak.
  • Çözüm: Değişmeyen, benzersiz bir kimlik (ör. MusteriID) kullanın.
  • Hata: Birincil Anahtarı Tanımlamamak: Bu, satırların benzersizliğini garanti etmez.
  • Çözüm: Her tabloya bir birincil anahtar tanımlayın.
  • Hata: Karmaşık Birleşik Anahtarlar: Birden çok sütundan oluşan birincil anahtarlar, performansı düşürebilir.
  • Çözüm: Mümkünse tek sütunlu birincil anahtar tercih edin.

2. Yabancı Anahtarlar (Foreign Key)

Rolü:

  • Tablolar Arası İlişki: Bir tablodaki bir sütun, başka bir tablonun birincil anahtarına referans vererek ilişkiler kurar.
  • Veri Bütünlüğü: Yabancı anahtar, yalnızca referans tablosunda mevcut olan değerlerin kullanılmasını sağlar (ör. bir sipariş, yalnızca mevcut bir müşteriye bağlanabilir).
  • Referans Bütünlüğü: Silme veya güncelleme işlemlerinde veri tutarlılığını korur (ör. ON DELETE CASCADE).

Doğru Kullanım Stratejileri:

  • Doğru Referans Tanımlama: Yabancı anahtar, yalnızca birincil anahtar veya benzersiz anahtar olan bir sütuna referans vermelidir.
  • Kısıtlamaları Belirtme: ON DELETE ve ON UPDATE gibi kurallar (ör. CASCADE, RESTRICT) ile davranış tanımlanmalıdır.
  • Performans Optimizasyonu: Yabancı anahtar sütunlarına indeks eklemek, JOIN işlemlerini hızlandırır.
  • Gerektiğinde Kapatma: Büyük veri yüklemelerinde geçici olarak yabancı anahtar kısıtlamaları devre dışı bırakılabilir, ancak sonrasında kontrol edilmelidir.

SQL Örneği:

CREATE TABLE Siparisler (
    SiparisID INT PRIMARY KEY AUTO_INCREMENT,
    MusteriID INT,
    SiparisTarihi DATE NOT NULL,
    FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID) ON DELETE CASCADE
);
  • Açıklama: MusteriID, Musteriler tablosunun MusteriID sütununa referans verir. Bir müşteri silinirse, ilgili siparişler de otomatik silinir (ON DELETE CASCADE).

Yaygın Hatalar ve Kaçınma Yolları:

  • Hata: Yabancı Anahtar Kısıtlamasını Tanımlamamak: Bu, geçersiz veri girişine (ör. olmayan bir müşteriye sipariş) izin verebilir.
  • Çözüm: Her ilişki için yabancı anahtar kısıtlaması tanımlayın.
  • Hata: Yanlış Silme/Güncelleme Kuralları: Örneğin, ON DELETE RESTRICT yerine CASCADE kullanmak, istenmeyen veri kayıplarına neden olabilir.
  • Çözüm: İş mantığına uygun kural seçin (ör. müşteri silindiğinde siparişlerin korunması gerekiyorsa RESTRICT kullanın).
  • Hata: Performans Sorunları: Çok fazla yabancı anahtar, yazma işlemlerini yavaşlatabilir.
  • Çözüm: Gerektiğinde yalnızca kritik ilişkiler için yabancı anahtar kullanın ve indeksleme yapın.

3. Benzersiz Tanımlayıcılar (Unique Constraint)

Rolü:

  • Benzersizlik Garantisi: Bir sütun veya sütun kombinasyonundaki değerlerin tekrar etmesini önler (ör. e-posta adresleri).
  • Alternatif Kimlik: Birincil anahtar dışında, başka bir benzersiz tanımlayıcı olarak kullanılabilir.
  • Veri Bütünlüğü: Aynı veri setinde çakışmaları engeller (ör. iki müşterinin aynı e-posta adresine sahip olması).

Doğru Kullanım Stratejileri:

  • Doğru Sütun Seçimi: Benzersizlik iş mantığı için kritik olan sütunlara uygulanmalıdır (ör. e-posta, TC Kimlik No).
  • NULL Değerlere İzin Verme: Benzersiz kısıtlamalar, NULL değerlere izin verebilir (birincil anahtardan farklı olarak), bu nedenle iş kuralına uygun şekilde tanımlanmalıdır.
  • Birleşik Benzersiz Kısıtlamalar: Birden çok sütunun kombinasyonunu benzersiz yapmak için kullanılabilir (ör. şehir ve posta kodu kombinasyonu).
  • Performans Düşüncesi: Benzersiz kısıtlamalar, otomatik olarak indeks oluşturur, bu da sorguları hızlandırır.

SQL Örneği:

CREATE TABLE Musteriler (
    MusteriID INT PRIMARY KEY AUTO_INCREMENT,
    Ad VARCHAR(50) NOT NULL,
    Eposta VARCHAR(100) UNIQUE,
    TCNo VARCHAR(11) UNIQUE
);
  • Açıklama: Eposta ve TCNo sütunları benzersiz olmalıdır; aynı e-posta veya TC No ile başka bir müşteri eklenemez.

Yaygın Hatalar ve Kaçınma Yolları:

  • Hata: Gereksiz Benzersiz Kısıtlamalar: Her sütuna benzersiz kısıtlama eklemek, performansı düşürebilir.
  • Çözüm: Yalnızca iş mantığı için gerekli sütunlara uygulayın.
  • Hata: Benzersizlik ve NULL Yanılgısı: Benzersiz kısıtlamalı bir sütunda birden fazla NULL değere izin verilmesi, beklenmeyen davranışlara yol açabilir.
  • Çözüm: NULL değerlerin iş mantığına etkisini analiz edin ve gerekiyorsa NOT NULL ekleyin.
  • Hata: Benzersiz Kısıtlamayı Birincil Anahtar ile Karıştırma: Benzersiz kısıtlamalar, birincil anahtar gibi zorunlu bir tanımlayıcı değildir.
  • Çözüm: Birincil anahtar için yalnızca bir sütun veya kombinasyon seçin; diğer benzersiz alanlar için UNIQUE kullanın.

4. Genel Kullanım Stratejileri
  • Tutarlı Veri Tipleri: Birincil ve yabancı anahtarlar aynı veri tipine sahip olmalıdır (ör. INT ile INT).
  • Dökümantasyon: Anahtarların amacı ve ilişkileri şema dökümantasyonunda açıkça belirtilmelidir.
  • Test ve Doğrulama: Anahtar kısıtlamalarının doğru çalıştığından emin olmak için test verileriyle deneme yapılmalıdır.
  • Esneklik: Gelecekteki ihtiyaçları karşılamak için anahtar tasarımı modüler ve ölçeklenebilir olmalıdır.

5. Yaygın Hatalardan Kaçınma
  • Hata: Anahtarların Eksik Tanımlanması:
  • Örnek: Bir tabloya birincil anahtar tanımlamamak, veri tekrarına yol açar.
  • Çözüm: Her tabloya birincil anahtar ekleyin ve ilişkiler için yabancı anahtarları unutmayın.
  • Hata: Karmaşık Anahtar Tasarımları:
  • Örnek: Birden çok sütundan oluşan birincil anahtarlar, bakım ve sorgulamayı zorlaştırır.
  • Çözüm: Mümkünse tek sütunlu, otomatik artan kimlikler kullanın.
  • Hata: İş Mantığını Göz Ardı Etme:
  • Örnek: Benzersiz olması gerekmeyen bir sütuna (ör. telefon numarası) benzersiz kısıtlama eklemek.
  • Çözüm: İş gereksinimlerini analiz ederek yalnızca gerekli kısıtlamaları uygulayın.
  • Hata: Yabancı Anahtarların Performans Etkisini Görmezden Gelme:
  • Örnek: Çok fazla yabancı anahtar, yazma işlemlerini yavaşlatabilir.
  • Çözüm: Kritik olmayan ilişkilerde programatik kontroller kullanmayı değerlendirin.

6. Gerçek Dünya Örneği

Bir Online Kitapçı Veritabanı:

  • Tablolar:
  • Kitaplar (KitapID INT PRIMARY KEY, Baslik VARCHAR(100) UNIQUE, Yazar VARCHAR(50))
  • Musteriler (MusteriID INT PRIMARY KEY, Ad VARCHAR(50), Eposta VARCHAR(100) UNIQUE)
  • Siparisler (SiparisID INT PRIMARY KEY, MusteriID INT, KitapID INT, Tarih DATE, FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID), FOREIGN KEY (KitapID) REFERENCES Kitaplar(KitapID))
  • Açıklama:
  • KitapID ve MusteriID birincil anahtarlar, her satırı benzersiz kılar.
  • Baslik ve Eposta benzersiz kısıtlamalara sahip, tekrar eden kitap veya e-posta engellenir.
  • Siparisler tablosunda MusteriID ve KitapID yabancı anahtarlar, yalnızca mevcut müşteri ve kitaplara sipariş verilmesini sağlar.
  • Hata Örneği: Eğer Siparisler tablosunda yabancı anahtar tanımlanmazsa, olmayan bir müşteriye veya kitaba sipariş eklenebilir. Bu, veri bütünlüğünü bozar.

7. SQL ile Hata Kontrolü Örneği

Yabancı anahtar kısıtlamasının çalıştığını test etmek:

-- Geçersiz bir MusteriID ile sipariş eklemeye çalışma
INSERT INTO Siparisler (SiparisID, MusteriID, SiparisTarihi) 
VALUES (101, 999, '2025-05-07');
  • Hata Mesajı: FOREIGN KEY constraint failed (Çünkü MusteriID=999 mevcut değil).
İndeksler ve kısıtlamalar
1. İndekslerin Veritabanı Performansına Etkisi

İndeks Nedir?
İndeks, bir tablonun belirli sütunlarındaki verilere hızlı erişim sağlamak için oluşturulan bir veri yapısıdır (genellikle B-Tree veya Hash tabanlı). İndeksler, sorguların (özellikle SELECT, WHERE, JOIN) performansını artırır.

Performans Üzerindeki Etkileri:

  • Avantajlar:
  • Hızlı Veri Erişimi: İndeksler, WHERE koşulları, JOIN işlemleri ve sıralama (ORDER BY) gibi sorgularda veri tarama süresini azaltır.
  • Sorgu Optimizasyonu: Örneğin, bir tablodaki MusteriID sütununa indeks eklenirse, SELECT * FROM Musteriler WHERE MusteriID = 100 sorgusu tam tablo taraması (full table scan) yerine indeks üzerinden çalışır.
  • Örnek: Bir e-ticaret sisteminde, sık sorgulanan UrunKodu sütununa indeks eklenmesi, ürün aramalarını hızlandırır.
  • Dezavantajlar:
  • Yazma Performansı Azalması: INSERT, UPDATE, DELETE işlemleri sırasında indekslerin güncellenmesi gerekir, bu da yazma işlemlerini yavaşlatır.
  • Depolama Alanı: İndeksler ek depolama alanı gerektirir.
  • Bakım Yükü: İndekslerin düzenli olarak optimize edilmesi (ör. yeniden oluşturulması) gerekir.
  • Örnek: Çok fazla indeks içeren bir tabloya veri eklemek, yazma işlemini ciddi şekilde yavaşlatabilir.

SQL Örneği (İndeks Oluşturma):

-- Musteriler tablosunda Eposta sütununa indeks oluşturma
CREATE INDEX idx_musteri_eposta ON Musteriler(Eposta);

-- İndeksli sorgu
SELECT * FROM Musteriler WHERE Eposta = 'ahmet@example.com';
  • Açıklama: idx_musteri_eposta indeksi, Eposta ile yapılan sorguları hızlandırır.

2. Kısıtlamaların Veritabanı Performansına Etkisi

Kısıtlamalar Nedir?
Kısıtlamalar (ör. PRIMARY KEY, FOREIGN KEY, UNIQUE, NOT NULL, CHECK), veri bütünlüğünü sağlamak için kullanılan kurallardır.

Performans Üzerindeki Etkileri:

  • Avantajlar:
  • Veri Bütünlüğü: Kısıtlamalar, yanlış veya tutarsız veri girişini engeller (ör. olmayan bir MusteriID ile sipariş eklenmesini önler).
  • Otomatik İndeksleme: PRIMARY KEY ve UNIQUE kısıtlamaları, otomatik olarak indeks oluşturur, bu da sorgu performansını artırır.
  • Örnek: UNIQUE kısıtlaması olan bir Eposta sütunu, aynı e-postanın tekrar eklenmesini engeller ve sorguları hızlandırır.
  • Dezavantajlar:
  • Yazma Performansı Azalması: Kısıtlamalar, her veri yazma işleminde kontrol edilir (ör. yabancı anahtar kontrolü), bu da INSERT ve UPDATE işlemlerini yavaşlatır.
  • Karmaşıklık Artışı: Çok fazla yabancı anahtar veya karmaşık CHECK kısıtlamaları, veritabanı işlemlerini karmaşıklaştırabilir.
  • Örnek: Bir tablodaki çok sayıda yabancı anahtar, toplu veri yüklemelerinde ciddi performans düşüşüne neden olabilir.

SQL Örneği (Kısıtlama Tanımlama):

CREATE TABLE Siparisler (
    SiparisID INT PRIMARY KEY,
    MusteriID INT,
    SiparisTarihi DATE NOT NULL,
    FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID),
    CONSTRAINT chk_tarih CHECK (SiparisTarihi >= '2020-01-01')
);
  • Açıklama: PRIMARY KEY otomatik indeks oluşturur, FOREIGN KEY veri bütünlüğünü sağlar, ancak her INSERT işleminde Musteriler tablosu kontrol edilir.

3. Hangi Durumlarda Ne Tür İndeksleme Kullanılmalı?

İndeks türleri ve kullanım senaryoları şunlardır:

a. B-Tree İndeksi
  • Ne Zaman Kullanılır?:
  • Genel amaçlı sorgular için (ör. WHERE, ORDER BY, JOIN).
  • Aralık sorguları (ör. WHERE Tarih BETWEEN '2025-01-01' AND '2025-12-31').
  • Eşittir karşılaştırmaları (ör. WHERE MusteriID = 100).
  • Örnek:
  CREATE INDEX idx_siparis_tarihi ON Siparisler(SiparisTarihi);
  • Avantaj: Çoğu veritabanında varsayılan indeks türüdür, geniş kullanım alanına sahiptir.
  • Dezavantaj: Çok büyük veri setlerinde performansı optimize etmek için ek ayarlar gerekebilir.
b. Hash İndeksi
  • Ne Zaman Kullanılır?:
  • Yalnızca eşittir karşılaştırmaları için (ör. WHERE UrunKodu = 'ABC123').
  • Yüksek hızlı, basit aramalar gereken durumlarda.
  • Örnek:
  CREATE INDEX idx_urun_kodu_hash ON Urunler(UrunKodu) USING HASH;
  • Avantaj: Eşittir sorgularında çok hızlıdır.
  • Dezavantaj: Aralık sorguları veya sıralama için uygun değildir.
c. Birleşik (Composite) İndeks
  • Ne Zaman Kullanılır?:
  • Birden çok sütunun birlikte sorgulandığı durumlar (ör. WHERE MusteriID = 100 AND SiparisTarihi = '2025-05-01').
  • Sorgularda sık kullanılan sütun kombinasyonları.
  • Örnek:
  CREATE INDEX idx_musteri_siparis ON Siparisler(MusteriID, SiparisTarihi);
  • Avantaj: Çoklu sütun sorgularını hızlandırır.
  • Dezavantaj: İndeks sırası önemlidir; yanlış sırada sütun seçimi performansı düşürebilir.
d. Benzersiz (Unique) İndeks
  • Ne Zaman Kullanılır?:
  • Bir sütunun veya sütun kombinasyonunun benzersiz olması gerektiğinde (ör. Eposta).
  • Hem veri bütünlüğü hem de performans artışı sağlar.
  • Örnek:
  CREATE UNIQUE INDEX idx_unq_eposta ON Musteriler(Eposta);
  • Avantaj: Tekrar eden verileri engeller ve sorguları hızlandırır.
  • Dezavantaj: Yazma işlemlerini yavaşlatabilir.
e. Kısmi (Partial) İndeks
  • Ne Zaman Kullanılır?:
  • Yalnızca belirli bir veri alt kümesi sık sorgulanıyorsa (ör. yalnızca aktif müşteriler).
  • Örnek:
  CREATE INDEX idx_aktif_musteriler ON Musteriler(MusteriID) WHERE Durum = 'Aktif';
  • Avantaj: Daha az depolama alanı kullanır ve performansı artırır.
  • Dezavantaj: Yalnızca belirli koşullar için çalışır.
f. Tam Metin (Full-Text) İndeksi
  • Ne Zaman Kullanılır?:
  • Metin tabanlı aramalar için (ör. ürün açıklamalarında anahtar kelime araması).
  • Örnek:
  CREATE FULLTEXT INDEX idx_urun_aciklama ON Urunler(Aciklama);
  SELECT * FROM Urunler WHERE MATCH(Aciklama) AGAINST('kitap');
  • Avantaj: Metin aramalarını hızlandırır.
  • Dezavantaj: Diğer indeks türlerinden daha fazla kaynak tüketebilir.

4. Optimum İndeks Stratejisi Nasıl Belirlenir?

Optimum indeks stratejisi, veritabanı kullanım desenlerine, iş gereksinimlerine ve performans hedeflerine bağlıdır. Aşağıdaki adımlar izlenmelidir:

a. Sorgu Analizi
  • Adım: En sık çalıştırılan sorguları (SELECT, WHERE, JOIN, GROUP BY, ORDER BY) belirleyin.
  • Araç: EXPLAIN veya ANALYZE komutlarıyla sorgu planlarını inceleyin.
  • Örnek:
  EXPLAIN SELECT * FROM Siparisler WHERE MusteriID = 100 AND SiparisTarihi = '2025-05-01';
  • Strateji: Sık kullanılan WHERE ve JOIN sütunlarına indeks ekleyin.
b. İş Yüküne Göre Önceliklendirme
  • Oku-Yaz Oranı: Okuma ağırlıklı sistemlerde (ör. raporlama sistemleri) daha fazla indeks kullanılabilir. Yazma ağırlıklı sistemlerde (ör. sipariş girişi) indeks sayısı sınırlanmalıdır.
  • Örnek: Bir raporlama sisteminde SiparisTarihi ve MusteriID için birleşik indeks eklemek faydalı olabilir.
c. İndeks Sütun Sırası
  • Kural: Birleşik indekslerde, en sık kullanılan sütunlar önce gelmelidir. Örneğin, WHERE MusteriID = 100 AND SiparisTarihi = '2025-05-01' için indeks (MusteriID, SiparisTarihi) şeklinde olmalıdır.
  • Örnek:
  CREATE INDEX idx_musteri_tarih ON Siparisler(MusteriID, SiparisTarihi);
d. Gereksiz İndekslerden Kaçınma
  • Adım: Kullanılmayan veya nadiren kullanılan indeksleri düzenli olarak kontrol edin ve kaldırın.
  • Araç: Veritabanı yönetim sistemlerinin indeks kullanım istatistiklerini (ör. PostgreSQL’de pg_stat_user_indexes) kullanın.
  • Örnek:
  DROP INDEX idx_musteri_eposta;
e. Performans Testleri
  • Adım: İndeks eklemeden önce ve sonra sorgu performansını test edin.
  • Araç: Benchmark araçları (ör. pgbench, sysbench) veya gerçek veri ile test.
  • Örnek: Bir indeks ekledikten sonra sorgu süresinin 100ms’den 10ms’ye düştüğünü gözlemleyin.
f. Depolama ve Bakım Düşüncesi
  • Adım: İndekslerin depolama maliyetini ve bakım yükünü değerlendirin.
  • Strateji: Büyük tablolarda yalnızca kritik sütunlara indeks ekleyin ve düzenli olarak indeksleri optimize edin (REINDEX).

5. Yaygın Hatalar ve Kaçınma Yolları
  • Hata: Her Sütuna İndeks Ekleme:
  • Sonuç: Yazma performansı düşer, depolama alanı artar.
  • Çözüm: Yalnızca sık sorgulanan sütunlara indeks ekleyin.
  • Hata: İndeks Sırasını Yanlış Belirleme:
  • Sonuç: Birleşik indeksler yanlış sırayla oluşturulursa sorgular optimize olmaz.
  • Çözüm: Sorgu desenlerini analiz ederek doğru sütun sırasını belirleyin.
  • Hata: Kısıtlamaların Performans Etkisini Görmezden Gelme:
  • Sonuç: Çok fazla yabancı anahtar, toplu veri yüklemelerini yavaşlatır.
  • Çözüm: Toplu işlemler sırasında kısıtlamaları geçici olarak devre dışı bırakın:
    sql ALTER TABLE Siparisler DISABLE CONSTRAINT fk_musteri; -- Veri yükleme ALTER TABLE Siparisler ENABLE CONSTRAINT fk_musteri;
  • Hata: İndeks Bakımını İhmal Etme:
  • Sonuç: Fragmente olmuş indeksler performansı düşürür.
  • Çözüm: Düzenli olarak indeksleri yeniden oluşturun:
    sql REINDEX TABLE Musteriler;

6. Gerçek Dünya Örneği

Bir E-Ticaret Sistemi:

  • Senaryo: Bir e-ticaret platformunda, kullanıcılar sık sık ürün araması (UrunAdi) ve sipariş geçmişi sorgulaması (MusteriID, SiparisTarihi) yapıyor.
  • İndeks Stratejisi:
  • Urunler tablosunda UrunAdi için tam metin indeksi:
    sql CREATE FULLTEXT INDEX idx_urun_adi ON Urunler(UrunAdi);
  • Siparisler tablosunda MusteriID ve SiparisTarihi için birleşik indeks:
    sql CREATE INDEX idx_siparis_musteri_tarih ON Siparisler(MusteriID, SiparisTarihi);
  • Eposta sütununa UNIQUE kısıtlaması ile otomatik indeks:
    sql ALTER TABLE Musteriler ADD CONSTRAINT unq_eposta UNIQUE (Eposta);
  • Sonuç: Ürün aramaları ve sipariş sorguları hızlanır, ancak veri ekleme işlemleri biraz yavaşlar.
  • Hata Örneği: Eğer her sütuna indeks eklenirse, sipariş ekleme süresi artar. Bu nedenle yalnızca kritik sütunlara indeks eklenmelidir.
İlişki Türleri
Bire-bir ilişkiler, Bire-çok ilişkiler ve Çoka-çok ilişkiler
1. Bire-Bir (1:1) İlişki

Tanım: Bir tablodaki bir satır, diğer tablodaki yalnızca bir satırla ilişkilidir ve bunun tersi de geçerlidir. Bu ilişki genellikle bir varlığın özelliklerini bölmek için kullanılır.

Kullanım Alanları:

  • Verilerin mantıksal olarak ayrılması (ör. güvenlik veya performans nedeniyle).
  • Nadiren erişilen ek bilgilerin ayrı bir tabloda saklanması.
  • Veritabanı normalizasyonu.

Örnek Senaryo: Bir Kisiler tablosu ve her kişinin yalnızca bir pasaport bilgisi olduğu bir Pasaportlar tablosu.

SQL Uygulaması:

-- Kisiler tablosu
CREATE TABLE Kisiler (
    KisiID INT PRIMARY KEY AUTO_INCREMENT,
    Ad VARCHAR(50) NOT NULL,
    Soyad VARCHAR(50) NOT NULL
);

-- Pasaportlar tablosu (1:1 ilişki)
CREATE TABLE Pasaportlar (
    PasaportID INT PRIMARY KEY,
    KisiID INT UNIQUE,
    PasaportNo VARCHAR(20) NOT NULL,
    GecerlilikTarihi DATE,
    FOREIGN KEY (KisiID) REFERENCES Kisiler(KisiID)
);

-- Veri ekleme
INSERT INTO Kisiler (Ad, Soyad) VALUES ('Ahmet', 'Yılmaz'), ('Ayşe', 'Kaya');
INSERT INTO Pasaportlar (PasaportID, KisiID, PasaportNo, GecerlilikTarihi)
VALUES (1, 1, 'P123456', '2030-01-01'), (2, 2, 'P789012', '2029-12-31');

-- Sorgu: Kişi ve pasaport bilgilerini birleştirme
SELECT K.Ad, K.Soyad, P.PasaportNo, P.GecerlilikTarihi
FROM Kisiler K
LEFT JOIN Pasaportlar P ON K.KisiID = P.KisiID;

Çıktı Örneği:

Ad      Soyad     PasaportNo  GecerlilikTarihi
Ahmet   Yılmaz    P123456     2030-01-01
Ayşe    Kaya      P789012     2029-12-31

Açıklama:

  • KisiID hem Kisiler tablosunda birincil anahtar hem de Pasaportlar tablosunda benzersiz bir yabancı anahtar olarak tanımlanmıştır.
  • UNIQUE kısıtlaması, bir kişinin yalnızca bir pasaportunun olmasını sağlar.
  • LEFT JOIN, pasaportu olmayan kişileri de listeler (opsiyonel).

Tasarım Notları:

  • 1:1 ilişkilerde genellikle bir tablonun birincil anahtarı, diğer tablonun hem birincil hem de yabancı anahtarı olabilir.
  • Performans veya güvenlik nedeniyle (ör. hassas verilerin ayrılması) tercih edilir.

2. Bire-Çok (1:N) İlişki

Tanım: Bir tablodaki bir satır, diğer tablodaki birden çok satırla ilişkilidir, ancak diğer tablodaki bir satır yalnızca bir satırla ilişkilidir. Bu, en yaygın ilişki türüdür.

Kullanım Alanları:

  • Hiyerarşik veriler (ör. bir müşteri birden çok sipariş verebilir).
  • Gruplanmış veriler (ör. bir departmanda birden çok çalışan).

Örnek Senaryo: Bir Musteriler tablosu ve her müşterinin birden çok siparişi olduğu bir Siparisler tablosu.

SQL Uygulaması:

-- Musteriler tablosu
CREATE TABLE Musteriler (
    MusteriID INT PRIMARY KEY AUTO_INCREMENT,
    Ad VARCHAR(50) NOT NULL,
    Eposta VARCHAR(100) UNIQUE
);

-- Siparisler tablosu (1:N ilişki)
CREATE TABLE Siparisler (
    SiparisID INT PRIMARY KEY AUTO_INCREMENT,
    MusteriID INT,
    SiparisTarihi DATE NOT NULL,
    ToplamTutar DECIMAL(10, 2),
    FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID)
);

-- Veri ekleme
INSERT INTO Musteriler (Ad, Eposta)
VALUES ('Ali', 'ali@example.com'), ('Zeynep', 'zeynep@example.com');

INSERT INTO Siparisler (MusteriID, SiparisTarihi, ToplamTutar)
VALUES (1, '2025-05-01', 150.50), (1, '2025-05-03', 89.90), (2, '2025-05-04', 200.00);

-- Sorgu: Müşterilerin siparişleriyle birlikte listelenmesi
SELECT M.Ad, M.Eposta, S.SiparisID, S.SiparisTarihi, S.ToplamTutar
FROM Musteriler M
LEFT JOIN Siparisler S ON M.MusteriID = S.MusteriID;

Çıktı Örneği:

Ad      Eposta              SiparisID  SiparisTarihi  ToplamTutar
Ali     ali@example.com     1          2025-05-01     150.50
Ali     ali@example.com     2          2025-05-03     89.90
Zeynep  zeynep@example.com  3          2025-05-04     200.00

Açıklama:

  • MusteriID, Musteriler tablosunda birincil anahtar, Siparisler tablosunda ise yabancı anahtardır.
  • Bir müşteri (MusteriID=1) birden çok siparişe sahip olabilir, ancak her sipariş yalnızca bir müşteriye aittir.
  • LEFT JOIN, siparişi olmayan müşterileri de listeler.

Tasarım Notları:

  • Yabancı anahtar, çok tarafındaki tabloda (ör. Siparisler) tanımlanır.
  • İndeksleme, MusteriID gibi sık sorgulanan yabancı anahtarlar için performans artırır:
  CREATE INDEX idx_siparis_musteri ON Siparisler(MusteriID);

3. Çoka-Çok (N:N) İlişki

Tanım: Bir tablodaki birden çok satır, diğer tablodaki birden çok satırla ilişkilidir. Bu ilişki, doğrudan uygulanamaz ve bir junction table (ara tablo) kullanılarak modellenir.

Kullanım Alanları:

  • Birden çok varlığın birbirine bağlanması (ör. öğrenciler ve dersler, ürünler ve kategoriler).
  • Esnek ve karmaşık ilişkilerin modellenmesi.

Örnek Senaryo: Bir Ogrenciler tablosu ve bir Dersler tablosu. Her öğrenci birden çok derse, her ders birden çok öğrenciye kayıtlı olabilir.

Junction Table (Ara Tablo) Nedir?:

  • Çoka-çok ilişkileri yönetmek için kullanılan bir ara tablodur.
  • Genellikle iki tablonun birincil anahtarlarını yabancı anahtar olarak içerir.
  • Ek öznitelikler (ör. kayıt tarihi) de saklayabilir.

SQL Uygulaması:

-- Ogrenciler tablosu
CREATE TABLE Ogrenciler (
    OgrenciID INT PRIMARY KEY AUTO_INCREMENT,
    Ad VARCHAR(50) NOT NULL
);

-- Dersler tablosu
CREATE TABLE Dersler (
    DersID INT PRIMARY KEY AUTO_INCREMENT,
    DersAdi VARCHAR(50) NOT NULL
);

-- Junction table: Ogrenci_Ders
CREATE TABLE Ogrenci_Ders (
    OgrenciID INT,
    DersID INT,
    KayitTarihi DATE,
    PRIMARY KEY (OgrenciID, DersID),
    FOREIGN KEY (OgrenciID) REFERENCES Ogrenciler(OgrenciID),
    FOREIGN KEY (DersID) REFERENCES Dersler(DersID)
);

-- Veri ekleme
INSERT INTO Ogrenciler (Ad) VALUES ('Ali'), ('Zeynep');
INSERT INTO Dersler (DersAdi) VALUES ('Matematik'), ('Fizik');
INSERT INTO Ogrenci_Ders (OgrenciID, DersID, KayitTarihi)
VALUES (1, 1, '2025-01-10'), (1, 2, '2025-01-12'), (2, 1, '2025-01-11');

-- Sorgu: Öğrencilerin aldığı dersler
SELECT O.Ad, D.DersAdi, OD.KayitTarihi
FROM Ogrenciler O
JOIN Ogrenci_Ders OD ON O.OgrenciID = OD.OgrenciID
JOIN Dersler D ON OD.DersID = D.DersID;

Çıktı Örneği:

Ad      DersAdi     KayitTarihi
Ali     Matematik   2025-01-10
Ali     Fizik       2025-01-12
Zeynep  Matematik   2025-01-11

Açıklama:

  • Ogrenci_Ders junction tablosu, OgrenciID ve DersID yabancı anahtarlarını içerir.
  • Birleşik birincil anahtar (OgrenciID, DersID), aynı öğrenci-ders kombinasyonunun tekrar eklenmesini engeller.
  • KayitTarihi gibi ek öznitelikler, ilişkiye özel bilgileri saklar.
  • JOIN işlemleri, öğrencilerin hangi derslere kayıtlı olduğunu gösterir.

Junction Table Tasarım Notları:

  • Birincil Anahtar: Genellikle junction tablosunda birleşik birincil anahtar (OgrenciID, DersID) kullanılır. Alternatif olarak, ayrı bir otomatik artan ID de eklenebilir.
  • Yabancı Anahtarlar: Her iki tablonun birincil anahtarlarına referans verir.
  • Ek Öznitelikler: İlişkiye özel veriler (ör. not, kayıt tarihi) junction tablosunda saklanabilir.
  • Performans: Yabancı anahtar sütunlarına indeks eklemek, JOIN performansını artırır:
  CREATE INDEX idx_ogrenci_ders ON Ogrenci_Ders(OgrenciID, DersID);

4. İlişki Türlerinin Karşılaştırması
ÖzellikBire-Bir (1:1)Bire-Çok (1:N)Çoka-Çok (N:N)
TanımBir satır yalnızca bir satırla ilişkilidirBir satır birden çok satırla ilişkilidirBirden çok satır birden çok satırla ilişkilidir
ÖrnekKişi-PasaportMüşteri-SiparişÖğrenci-Ders
Tablo YapısıTek yabancı anahtar, genellikle UNIQUEYabancı anahtar çok tarafındaJunction table ile iki yabancı anahtar
Kullanım AlanıVerilerin ayrılması, güvenlikHiyerarşik verilerKarmaşık ilişkiler
SQL KompleksliğiBasitOrtaDaha karmaşık (JOIN ile)

5. Junction Table Kullanımının Detayları

Neden Junction Table Gereklidir?:

  • Çoka-çok ilişkilerde, iki tabloyu doğrudan bağlamak mümkün değildir çünkü bu, normalizasyon kurallarını ihlal eder ve veri tekrarına yol açar.
  • Junction table, bu ilişkiyi normalleştirir ve her bir ilişkiyi ayrı bir satır olarak saklar.

Tasarım İlkeleri:

  • Minimal Yapı: Yalnızca gerekli yabancı anahtarlar ve (varsa) ek öznitelikler içermelidir.
  • Benzersizlik: Birleşik birincil anahtar veya UNIQUE kısıtlaması, aynı ilişkinin tekrar eklenmesini önler.
  • Performans Optimizasyonu: Yabancı anahtar sütunlarına indeks eklenmelidir.
  • Esneklik: Ek öznitelikler (ör. KayitTarihi, Not) ilişkiye özel veriler için kullanılabilir.

Örnek (Ek Öznitelikli Junction Table):
Bir e-ticaret sisteminde ürünler ve kategoriler arasındaki çoka-çok ilişki:

CREATE TABLE Urunler (
    UrunID INT PRIMARY KEY AUTO_INCREMENT,
    UrunAdi VARCHAR(100) NOT NULL
);

CREATE TABLE Kategoriler (
    KategoriID INT PRIMARY KEY AUTO_INCREMENT,
    KategoriAdi VARCHAR(50) NOT NULL
);

CREATE TABLE Urun_Kategori (
    UrunID INT,
    KategoriID INT,
    EklenmeTarihi DATE,
    PRIMARY KEY (UrunID, KategoriID),
    FOREIGN KEY (UrunID) REFERENCES Urunler(UrunID),
    FOREIGN KEY (KategoriID) REFERENCES Kategoriler(KategoriID)
);

-- Veri ekleme
INSERT INTO Urunler (UrunAdi) VALUES ('Laptop'), ('Telefon');
INSERT INTO Kategoriler (KategoriAdi) VALUES ('Elektronik'), ('Bilgisayar');
INSERT INTO Urun_Kategori (UrunID, KategoriID, EklenmeTarihi)
VALUES (1, 1, '2025-05-01'), (1, 2, '2025-05-02'), (2, 1, '2025-05-03');

-- Sorgu
SELECT U.UrunAdi, K.KategoriAdi, UK.EklenmeTarihi
FROM Urunler U
JOIN Urun_Kategori UK ON U.UrunID = UK.UrunID
JOIN Kategoriler K ON UK.KategoriID = K.KategoriID;

Çıktı Örneği:

UrunAdi   KategoriAdi   EklenmeTarihi
Laptop    Elektronik    2025-05-01
Laptop    Bilgisayar    2025-05-02
Telefon   Elektronik    2025-05-03

Açıklama: Urun_Kategori junction tablosu, bir ürünün birden çok kategoriye ve bir kategorinin birden çok ürüne bağlanmasını sağlar. EklenmeTarihi, ilişkiye özel bir özniteliktir.


6. Yaygın Hatalar ve Kaçınma Yolları
  • Hata: 1:1 ve 1:N İçin Gereksiz Junction Table Kullanımı:
  • Sonuç: Tasarım karmaşıklaşır ve performans düşer.
  • Çözüm: 1:1 için benzersiz yabancı anahtar, 1:N için doğrudan yabancı anahtar kullanın.
  • Hata: Junction Table’da Yetersiz Kısıtlamalar:
  • Sonuç: Aynı öğrenci-ders kombinasyonunun tekrar eklenmesi.
  • Çözüm: Birleşik birincil anahtar veya UNIQUE kısıtlaması tanımlayın.
  • Hata: Performans Optimizasyonu Eksikliği:
  • Sonuç: Çoklu JOIN işlemleri yavaşlar.
  • Çözüm: Yabancı anahtar sütunlarına indeks ekleyin.
  • Hata: İş Mantığını Yanlış Modelleme:
  • Sonuç: Örneğin, bir kişinin birden çok pasaportu olabileceği bir senaryoda 1:1 yerine 1:N kullanmak.
  • Çözüm: İş gereksinimlerini dikkatlice analiz edin.

7. Gerçek Dünya Örneği

Bir Eğitim Platformu:

  • 1:1: Her öğrencinin bir kullanıcı profili (Kullanicilar ve Profiller).
  • 1:N: Bir öğretmenin birden çok dersi (Ogretmenler ve Dersler).
  • N:N: Öğrencilerin ve derslerin ilişkisi (Ogrenciler, Dersler, Ogrenci_Ders junction table).
  • SQL Tasarımı:
  • Profiller.KullaniciID benzersiz yabancı anahtar ile Kullanicilar tablosuna bağlanır.
  • Dersler.OgretmenID yabancı anahtar ile Ogretmenler tablosuna bağlanır.
  • Ogrenci_Ders junction tablosu, öğrencilerin ders kayıtlarını yönetir.
Zorunlu ve isteğe bağlı ilişkiler
Zorunlu İlişkiler
  • Tanım: Bir tablodaki bir kaydın, başka bir tablodaki en az bir kayıtla ilişkili olması gerektiği durumlardır. Örneğin, bir Sipariş tablosundaki her kaydın mutlaka bir Müşteri kaydına bağlı olması zorunlu bir ilişkidir.
  • Veritabanı Tasarımına Etkisi:
  • Yabancı Anahtar Kısıtlamaları: Zorunlu ilişkilerde, yabancı anahtar (foreign key) sütunu NOT NULL olarak tanımlanır. Bu, ilgili tablodaki her kaydın geçerli bir anahtar değerine sahip olmasını zorunlu kılar.
  • Veri Bütünlüğü: Zorunlu ilişkiler, veri tutarlılığını sağlar. Örneğin, bir siparişin müşterisiz kaydedilmesi engellenir, bu da veri anomalilerini önler.
  • Tasarım Kısıtlamaları: Zorunlu ilişkiler, veri girişini sıkı bir şekilde kontrol eder. Ancak, bu durum esneklik gerektiren senaryolarda (örneğin, bir siparişin henüz bir müşteriye atanmadığı durumlar) tasarımda ek çözümler gerektirebilir.
  • Performans: Zorunlu ilişkiler, genellikle birleştirme (join) işlemlerinde daha az NULL kontrolü gerektirir, bu da sorgu performansını artırabilir.
İsteğe Bağlı İlişkiler
  • Tanım: Bir tablodaki bir kaydın, başka bir tablodaki bir kayıtla ilişkili olması gerekmediği durumlardır. Örneğin, bir Çalışan tablosunda her çalışanın bir Yönetici ile ilişkili olması zorunlu olmayabilir.
  • Veritabanı Tasarımına Etkisi:
  • Yabancı Anahtar Esnekliği: İsteğe bağlı ilişkilerde, yabancı anahtar sütunu NULL değer alabilir. Bu, bir kaydın ilgili tabloyla bağlantısı olmayabileceğini gösterir.
  • Veri Bütünlüğü: İsteğe bağlı ilişkiler daha esnek bir tasarım sağlar, ancak NULL değerler veri bütünlüğünü karmaşıklaştırabilir. Örneğin, bir sorguda NULL değerlerin yanlış yorumlanması hatalara yol açabilir.
  • Tasarım Esnekliği: İsteğe bağlı ilişkiler, uygulama gereksinimlerinde belirsizlik veya eksik veri durumlarını destekler. Örneğin, bir çalışanın yöneticisi henüz atanmamış olabilir.
  • Performans: NULL değerlerin varlığı, sorgularda ek kontroller (örneğin, IS NULL veya IS NOT NULL) gerektirebilir, bu da performans üzerinde hafif bir etki yaratabilir.
NULL Değerlerin Yönetimi

NULL değerler, isteğe bağlı ilişkilerde sıkça ortaya çıkar ve veritabanı tasarımında dikkatli bir şekilde yönetilmelidir. NULL, bir sütunda veri eksikliğini veya bilinmezliği ifade eder, ancak yanlış kullanıldığında sorgu sonuçlarında hatalara veya beklenmeyen davranışlara neden olabilir.

NULL Değerlerin Yönetiminde Karşılaşılan Zorluklar:
  1. Anlamsal Belirsizlik: NULL, “veri yok”, “bilinmiyor” veya “geçerli değil” gibi farklı anlamlar taşıyabilir. Bu, uygulama geliştiricilerinin NULL değerleri doğru yorumlamasını zorlaştırır.
  2. Sorgu Karmaşıklığı: NULL değerler, SQL sorgularında özel işlem gerektirir. Örneğin, = operatörü yerine IS NULL veya IS NOT NULL kullanılmalıdır.
  3. Performans Etkisi: NULL değerlerin sık kullanımı, indeksleme ve sorgu optimizasyonunu olumsuz etkileyebilir.
  4. Veri Bütünlüğü Sorunları: NULL değerlerin yanlış kullanımı, veri tutarlılığını bozabilir. Örneğin, bir sütunda NULL yerine varsayılan bir değer kullanılması daha uygun olabilir.
NULL Değerlerin Yönetiminde En İyi Uygulamalar:

NULL Kullanımını Minimize Edin:

  • Mümkünse, NULL yerine varsayılan değerler (default values) kullanın. Örneğin, bir Durum sütunu için NULL yerine “Bilinmiyor” veya “Yok” gibi bir değer tanımlayın.
  • Zorunlu ilişkileri tercih ederek NULL kullanımını azaltın, ancak bu karar uygulama gereksinimlerine uygun olmalıdır.

Anlamı Netleştirin:

  • NULL’un neyi ifade ettiğini tasarım aşamasında belgeleyin. Örneğin, bir YöneticiID sütununda NULL, “çalışanın yöneticisi yok” mu yoksa “yönetici bilgisi bilinmiyor” mu anlamına geliyor? Bu, uygulama geliştiricileri için kritik bir bilgidir.

Yabancı Anahtar Kısıtlamalarını Doğru Kullanın:

  • İsteğe bağlı ilişkilerde yabancı anahtar sütunlarının NULL alabileceğini unutmayın, ancak bu sütunların veri bütünlüğünü sağlamak için doğru kısıtlamalarla (constraints) tanımlandığından emin olun.
  • Zorunlu ilişkilerde NOT NULL kısıtlamasını kullanarak veri girişinde hata olasılığını azaltın.

Sorgularda NULL Kontrolü Yapın:

  • SQL sorgularında NULL değerleri doğru şekilde ele alın. Örneğin, bir birleştirme işleminde (join) LEFT JOIN kullanarak NULL değerleri dahil edebilir veya COALESCE fonksiyonuyla NULL değerleri varsayılan bir değere çevirebilirsiniz.
  • Örnek: SELECT COALESCE(YoneticiID, 0) AS YoneticiID FROM Calisanlar

İndeksleme ve Performans Optimizasyonu:

  • NULL değerler indekslerde yer kaplar ve sorgu performansını etkileyebilir. Sık sorgulanan sütunlarda NULL kullanımını azaltarak indeks verimliliğini artırın.
  • Gerekirse, NULL değerleri filtrelemek için partial index (kısmi indeks) gibi gelişmiş indeksleme tekniklerini kullanın.

Veritabanı Normalizasyonunu Gözden Geçirin:

  • NULL değerlerin yoğun olduğu bir tasarım, normalizasyon kurallarına uygun olmayabilir. Örneğin, bir tabloda çok sayıda NULL içeren sütunlar varsa, bu verileri ayrı bir tabloya taşımayı düşünün (örneğin, bir EkBilgiler tablosu).

Uygulama Katmanında Kontrol:

  • Veritabanı seviyesinde NULL değerlerin yönetimini desteklemek için uygulama katmanında da doğrulama ve hata yönetimi yapın. Örneğin, bir formda kullanıcıdan zorunlu olmayan bir alan boş bırakıldığında, bu durumun NULL olarak kaydedileceğini garanti edin.

Test ve Doğrulama:

  • Veritabanı tasarımını test ederken, NULL değerlerin sorgu sonuçları üzerindeki etkisini kontrol edin. Özellikle, birleştirme işlemleri ve toplu veri analizlerinde NULL değerlerin beklenmedik sonuçlara yol açmadığından emin olun.
Örnek Senaryo

Senaryo: Bir veritabanında Musteriler ve Siparisler tabloları var. Her siparişin bir müşteriye bağlı olması zorunlu değil (isteğe bağlı ilişki).

  • Tasarım:
  • Siparisler tablosunda MusteriID sütunu yabancı anahtar olarak tanımlanır ve NULL alabilir.
  • Şema: CREATE TABLE Musteriler ( MusteriID INT PRIMARY KEY, Ad VARCHAR(50) ); CREATE TABLE Siparisler ( SiparisID INT PRIMARY KEY, MusteriID INT NULL, FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID) );
  • NULL Yönetimi:
  • Bir sipariş müşterisiz kaydedilebilir (MusteriID = NULL).
  • Sorgu örneği: Müşterisiz siparişleri listelemek için:
    sql SELECT * FROM Siparisler WHERE MusteriID IS NULL;
  • Müşteri bilgisiyle birlikte siparişleri listelemek için LEFT JOIN kullanılır: SELECT s.SiparisID, m.Ad FROM Siparisler s LEFT JOIN Musteriler m ON s.MusteriID = m.MusteriID;
  • En İyi Uygulama:
  • Eğer müşterisiz siparişler nadir bir durumsa, MusteriID için bir varsayılan değer (örneğin, “Misafir” müşteriye işaret eden bir MusteriID) tanımlanabilir. Bu, NULL kullanımını azaltır ve sorguları basitleştirir.
İleri Düzey Kavramlar
Normalleştirme
Normalleştirme prensipleri
Normalleştirme Prensiplerinin Temel Amaçları
  1. Veri Fazlalığını Azaltmak: Aynı verinin birden fazla yerde saklanmasını önleyerek depolama verimliliğini artırmak.
  2. Veri Bütünlüğünü Sağlamak: Veri tutarlılığını korumak için bağımlılıkları doğru yönetmek.
  3. Anomalileri Önlemek: Ekleme (insertion), silme (deletion) ve güncelleme (update) işlemlerinde veri tutarsızlıklarını engellemek.
  4. Esnek ve Bakımı Kolay Tasarım: Veritabanının gelecekteki değişikliklere uyum sağlayabilmesi için modüler bir yapı oluşturmak.

1. Normal Form (1NF – Birinci Normal Form)
Tanım ve Kurallar:
  • Tüm sütunlar atomik (bölünemez) değerler içermelidir, yani bir sütunda birden fazla değer veya liste bulunamaz.
  • Her sütun benzersiz bir isme sahip olmalıdır.
  • Tabloda yinelenen satırlar (duplicate rows) olmamalıdır; her satır birincil anahtar (primary key) ile benzersiz şekilde tanımlanmalıdır.
  • Satır sırası veya sütun sırası önemli değildir.
Neden Gerekli?
  • 1NF, verilerin düzenli ve sorgulanabilir bir yapıda olmasını sağlar.
  • Atomik değerler, SQL sorgularının daha kolay yazılmasını ve veri işlenmesini sağlar.
  • Yinelenen satırların olmaması, veri fazlalığını ve tutarsızlığı önler.
Örnek:

Normalleştirilmemiş Tablo (1NF’ye uymuyor):

ÖğrenciIDAdSoyadDersler
1Ali VeliMatematik, Fizik, Kimya
2Ayşe YılmazBiyoloji, Kimya

Sorunlar:

  • Dersler sütunu atomik değil; birden fazla değeri virgülle ayrılmış şekilde içeriyor.
  • Bu yapıda, belirli bir dersi sorgulamak zor (örneğin, “Kimya alan öğrenciler kimler?”).
  • Ders ekleme veya silme işlemleri karmaşık ve hata yapmaya açık.

1NF’ye Uyarlanmış Tablo:

ÖğrenciIDAdSoyadDers
1Ali VeliMatematik
1Ali VeliFizik
1Ali VeliKimya
2Ayşe YılmazBiyoloji
2Ayşe YılmazKimya

Değişiklikler:

  • Dersler sütunu atomik hale getirildi; her satır tek bir dersi temsil ediyor.
  • Birincil anahtar olarak (ÖğrenciID, Ders) kombinasyonu kullanılabilir.
Önlenen Anomaliler:
  • Ekleme Anomalisi: Yeni bir ders eklemek için tüm öğrencilerin ders listesini güncellemek gerekmez.
  • Silme Anomalisi: Bir öğrencinin bir dersini silmek, diğer derslerini etkilemez.
  • Güncelleme Anomalisi: Bir dersin adı değiştiğinde, yalnızca ilgili satır güncellenir.

2. Normal Form (2NF – İkinci Normal Form)
Tanım ve Kurallar:
  • Tablo zaten 1NF’de olmalıdır.
  • Tüm non-key (anahtar olmayan) sütunlar, birincil anahtarın tamamına fonksiyonel olarak bağımlı olmalıdır. Yani, anahtarın bir alt kümesine bağımlı olmamalıdır (kısmi bağımlılık olmamalıdır).
  • Genellikle, bileşik anahtar (composite key) içeren tablolarda uygulanır.
Neden Gerekli?
  • 2NF, kısmi bağımlılıkları ortadan kaldırarak veri fazlalığını azaltır.
  • Verilerin yalnızca bir kez saklanmasını sağlar, böylece güncelleme işlemleri daha tutarlı olur.
Örnek:

1NF’de Olan Ancak 2NF’ye Uymayan Tablo:

ÖğrenciIDDersIDDersAdıÖğretmen
1101MatematikAhmet Hoca
1102FizikAyşe Hoca
2101MatematikAhmet Hoca

Sorunlar:

  • Birincil anahtar (ÖğrenciID, DersID)’dir.
  • DersAdı ve Öğretmen sütunları yalnızca DersID’ye bağlıdır, yani anahtarın yalnızca bir kısmına (kısmi bağımlılık).
  • Bu, veri fazlalığına neden olur (DersAdı ve Öğretmen her ders için tekrarlanır).

2NF’ye Uyarlanmış Tablolar:

  1. Dersler Tablosu: DersID DersAdı Öğretmen 101 Matematik Ahmet Hoca 102 Fizik Ayşe Hoca
  2. ÖğrenciDers Tablosu:
    ÖğrenciID DersID
    1 101
    1 102
    2 101 Değişiklikler:
    • Kısmi bağımlılıklar ayrıldı: DersAdı ve Öğretmen yalnızca DersID’ye bağlı olduğu için ayrı bir tabloda saklandı.
    • ÖğrenciDers tablosu, yalnızca öğrenciler ve dersler arasındaki ilişkiyi tutar.
    Önlenen Anomaliler:
    • Ekleme Anomalisi: Yeni bir ders eklemek için öğrenci kaydı gerekmez; sadece Dersler tablosuna eklenir.
    • Silme Anomalisi: Bir öğrencinin bir dersi bırakması, dersin bilgilerini (DersAdı, Öğretmen) silmez.
    • Güncelleme Anomalisi: Bir dersin öğretmeni değiştiğinde, yalnızca Dersler tablosunda tek bir satır güncellenir, birden fazla satır değil.
    3. Normal Form (3NF – Üçüncü Normal Form)Tanım ve Kurallar:
    • Tablo zaten 2NF’de olmalıdır.
    • Tüm non-key sütunlar, birincil anahtara doğrudan bağımlı olmalıdır ve başka bir non-key sütuna bağımlı olmamalıdır (geçişli bağımlılık olmamalıdır).
    Neden Gerekli?
    • 3NF, geçişli bağımlılıkları ortadan kaldırarak veri fazlalığını daha da azaltır.
    • Veri tutarlılığını artırır ve güncelleme işlemlerini basitleştirir.
    Örnek: 2NF’de Olan Ancak 3NF’ye Uymayan Tablo: SiparişID MüşteriID MüşteriAdı Şehir 1 101 Ali Veli İstanbul 2 102 Ayşe Yılmaz Ankara 3 101 Ali Veli İstanbul Sorunlar:
    • Birincil anahtar SiparişID’dir.
    • MüşteriAdı ve Şehir sütunları MüşteriID’ye bağlıdır, ancak MüşteriID bir non-key sütundur (geçişli bağımlılık: SiparişID → MüşteriID → MüşteriAdı, Şehir).
    • Bu, veri fazlalığına neden olur (MüşteriAdı ve Şehir her sipariş için tekrarlanır).
    3NF’ye Uyarlanmış Tablolar:
    1. Müşteriler Tablosu: MüşteriID MüşteriAdı Şehir 101 Ali Veli İstanbul 102 Ayşe Yılmaz Ankara
    2. Siparişler Tablosu:
      SiparişID MüşteriID
      1 101
      2 102
      3 101 Değişiklikler:
      • Geçişli bağımlılıklar ayrıldı: MüşteriAdı ve Şehir yalnızca MüşteriID’ye bağlı olduğu için ayrı bir tabloda saklandı.
      • Siparişler tablosu yalnızca sipariş ve müşteri ilişkisini tutar.
      Önlenen Anomaliler:
      • Ekleme Anomalisi: Yeni bir müşteri eklemek için bir sipariş kaydı gerekmez; sadece Müşteriler tablosuna eklenir.
      • Silme Anomalisi: Bir sipariş silindiğinde, müşteri bilgileri kaybolmaz.
      • Güncelleme Anomalisi: Bir müşterinin şehri değiştiğinde, yalnızca Müşteriler tablosunda tek bir satır güncellenir.
      Boyce-Codd Normal Form (BCNF)Tanım ve Kurallar:
      • Tablo zaten 3NF’de olmalıdır.
      • Her determinant (bir sütunun başka bir sütunu belirlediği durum), bir candidate key (aday anahtar) olmalıdır.
      • BCNF, 3NF’den daha katıdır ve bazı özel durumlarda fonksiyonel bağımlılıkları ele alır.
      Neden Gerekli?
      • BCNF, 3NF’nin ele alamadığı bazı bağımlılık anomalilerini giderir.
      • Özellikle, birden fazla aday anahtar içeren tablolarda veri bütünlüğünü sağlar.
      Örnek: 3NF’de Olan Ancak BCNF’ye Uymayan Tablo: ÖğrenciID DersID Öğretmen 1 101 Ahmet Hoca 1 102 Ayşe Hoca 2 101 Ahmet Hoca Bağımlılıklar:
      • Aday anahtarlar: (ÖğrenciID, DersID) ve (ÖğrenciID, Öğretmen).
      • DersID → Öğretmen (her ders yalnızca bir öğretmen tarafından verilir).
      • Ancak, DersID bir aday anahtar değildir, bu yüzden tablo BCNF’ye uymaz.
      Sorunlar:
      • Öğretmen bilgisi DersID’ye bağlı olduğu için veri fazlalığı oluşur.
      • Bir dersin öğretmeni değiştiğinde, birden fazla satır güncellenmelidir.
      BCNF’ye Uyarlanmış Tablolar:
      1. Dersler Tablosu: DersID Öğretmen 101 Ahmet Hoca 102 Ayşe Hoca
      2. ÖğrenciDers Tablosu:
        ÖğrenciID DersID
        1 101
        1 102
        2 101 Değişiklikler:
        • DersID → Öğretmen bağımlılığı ayrı bir tabloda çözüldü.
        • Tablo, tüm determinantların aday anahtar olduğu bir yapıya getirildi.
        Önlenen Anomaliler:
        • Güncelleme Anomalisi: Bir dersin öğretmeni değiştiğinde, yalnızca Dersler tablosunda tek bir satır güncellenir.
        • Ekleme/Silme Anomalisi: Ders ve öğretmen bilgileri, öğrenci kayıtlarından bağımsız olarak yönetilebilir.
        4. Normal Form (4NF – Dördüncü Normal Form)Tanım ve Kurallar:
        • Tablo zaten BCNF’de olmalıdır.
        • Tablo, çok değerli bağımlılıklar (multi-valued dependencies) içermemelidir. Çok değerli bağımlılık, bir sütunun değerinin başka bir sütunun değerine bağlı olması, ancak bu bağımlılığın fonksiyonel olmaması durumudur.
        Neden Gerekli?
        • 4NF, birden fazla bağımsız çok değerli ilişkinin aynı tabloda saklanmasından kaynaklanan veri fazlalığını ve anomalileri önler.
        Örnek: BCNF’de Olan Ancak 4NF’ye Uymayan Tablo: ÖğrenciID Ders Hobi 1 Matematik Futbol 1 Matematik Müzik 1 Fizik Futbol 1 Fizik Müzik Sorunlar:
        • Ders ve Hobi, ÖğrenciID’ye bağlıdır, ancak birbirinden bağımsızdır (çok değerli bağımlılık: ÖğrenciID →→ Ders | Hobi).
        • Bu, veri fazlalığına neden olur (aynı ders ve hobi kombinasyonları tekrarlanır).
        4NF’ye Uyarlanmış Tablolar:
        1. ÖğrenciDers Tablosu: ÖğrenciID Ders 1 Matematik 1 Fizik
        2. ÖğrenciHobi Tablosu:
          ÖğrenciID Hobi
          1 Futbol
          1 Müzik Değişiklikler:
          • Çok değerli bağımlılıklar ayrı tablolara bölündü.
          • Her tablo, bağımsız ilişkileri temsil eder.
          Önlenen Anomaliler:
          • Ekleme Anomalisi: Yeni bir hobi eklemek için ders bilgisi gerekmez.
          • Silme Anomalisi: Bir ders silindiğinde, hobi bilgileri kaybolmaz.
          • Güncelleme Anomalisi: Bir öğrencinin hobisi değiştiğinde, yalnızca ilgili tablo güncellenir.
          5. Normal Form (5NF – Beşinci Normal Form)Tanım ve Kurallar:
          • Tablo zaten 4NF’de olmalıdır.
          • Tablo, birleştirme bağımlılıkları (join dependencies) içermemelidir. Yani, tablo yalnızca birleştirme yoluyla kayıpsız (lossless) bir şekilde yeniden oluşturulabiliyorsa 5NF’dedir.
          • 5NF, bir tablonun birden fazla ilişkisel bağımlılığı aynı anda temsil etmesini önler.
          Neden Gerekli?
          • 5NF, karmaşık ilişkisel bağımlılıkların neden olduğu veri fazlalığını ve anomalileri giderir.
          • Genellikle çok nadir durumlarda uygulanır, çünkü çoğu veritabanı 3NF veya 4NF’de yeterince optimize edilmiştir.
          Örnek: 4NF’de Olan Ancak 5NF’ye Uymayan Tablo: ÇalışanID Proje Departman 1 Proje A IT 1 Proje B IT 2 Proje A Pazarlama Sorunlar:
          • Tablo, ÇalışanID, Proje ve Departman arasındaki ilişkiyi temsil ediyor.
          • Ancak, bu tablo birleştirme bağımlılığı içeriyor: Örneğin, ÇalışanID → Proje ve ÇalışanID → Departman ilişkileri, Proje → Departman gibi bir bağımlılık yaratabilir.
          • Bu, gereksiz veri tekrarına ve bakım zorluklarına neden olabilir.
          5NF’ye Uyarlanmış Tablolar:
          1. ÇalışanProje Tablosu: ÇalışanID Proje 1 Proje A 1 Proje B 2 Proje A
          2. ÇalışanDepartman Tablosu: ÇalışanID Departman 1 IT 2 Pazarlama
          3. ProjeDepartman Tablosu (gerekirse):
            Proje Departman
            Proje A IT
            Proje A Pazarlama
            Proje B IT Değişiklikler:
            • Birleştirme bağımlılıkları ayrı tablolara bölündü.
            • Her tablo, yalnızca bir ilişki türünü temsil eder.
            Önlenen Anomaliler:
            • Ekleme Anomalisi: Yeni bir proje-departman ilişkisi eklemek için çalışan kaydı gerekmez.
            • Silme Anomalisi: Bir çalışanın projesi silindiğinde, departman bilgileri kaybolmaz.
            • Güncelleme Anomalisi: Bir projenin departmanı değiştiğinde, yalnızca ilgili tablo güncellenir.
            Normalleştirme Sürecinin Genel Değerlendirmesi
            • 1NF, verilerin atomik ve düzenli olmasını sağlar, temel sorgulama ve veri tutarlılığı için gereklidir.
            • 2NF, kısmi bağımlılıkları gidererek veri fazlalığını azaltır.
            • 3NF, geçişli bağımlılıkları ortadan kaldırarak daha fazla optimizasyon sağlar.
            • BCNF, özel bağımlılık durumlarını ele alarak veri bütünlüğünü güçlendirir.
            • 4NF, çok değerli bağımlılıkları çözerek bağımsız ilişkileri ayırır.
            • 5NF, karmaşık birleştirme bağımlılıklarını gidererek en yüksek düzeyde normalizasyon sağlar.
            Normalleştirmenin Sınırları ve Pratik Uygulama
            • Aşırı Normalizasyon: 5NF’ye kadar normalleştirme, genellikle karmaşıklık ve performans sorunlarına yol açabilir (örneğin, çok fazla birleştirme işlemi). Çoğu pratik veritabanı tasarımı 3NF veya BCNF’de durur.
            • Denormalizasyon: Performans için bazen veri fazlalığı kasıtlı olarak kabul edilir (örneğin, sık sorgulanan veriler için).
            • Uygulama Gereksinimlerine Göre Tasarım: Normalleştirme, iş gereksinimlerine ve sorgu performansına göre dengelenmelidir.
            Sonuç Normalleştirme, veritabanı tasarımında veri tutarlılığı ve verimlilik sağlamak için kritik bir süreçtir. Her normal form, belirli türde veri fazlalığını ve anomalileri önler. 1NF’den 5NF’ye kadar her adım, daha karmaşık bağımlılıkları çözerek veritabanını daha modüler ve bakım yapılabilir hale getirir. Ancak, pratikte normalleştirme seviyesi, uygulamanın ihtiyaçlarına ve performans hedeflerine göre belirlenmelidir.
Denormalizasyon ve performans optimizasyonu
Denormalizasyon Nedir?

Denormalizasyon, normalleştirilmiş (genellikle 3NF veya BCNF’de) bir veritabanında, veri fazlalığını artırarak tabloları birleştirme (join) işlemlerini azaltmak, sorgu performansını iyileştirmek veya uygulama gereksinimlerini karşılamak için yapılan bir tasarım değişikliğidir. Örneğin, sık erişilen verileri tek bir tabloda bir araya getirmek veya hesaplanmış değerleri önbelleğe almak denormalizasyon tekniklerindendir.


Denormalizasyon Ne Zaman Uygulanmalıdır?

Denormalizasyon, aşağıdaki durumlarda düşünülmelidir:

Yüksek Sorgu Performansı Gereksinimleri:

  • Çok sayıda birleştirme (join) işlemi, özellikle büyük veri kümelerinde, sorgu performansını ciddi şekilde yavaşlatıyorsa.
  • Gerçek zamanlı uygulamalarda (örneğin, e-ticaret platformları, sosyal medya) hızlı yanıt süreleri kritikse.

Sık Erişilen Veriler:

  • Belirli veriler sıkça sorgulanıyorsa ve bu verilerin birleştirme işlemleriyle toplanması maliyetliyse.
  • Örnek: Bir raporda her zaman müşteri adı ve sipariş toplamı birlikte gerekiyorsa, bu veriler tek bir tabloda saklanabilir.

Okuma Ağırlıklı Sistemler:

  • Veritabanında okuma (SELECT) işlemleri, yazma (INSERT, UPDATE, DELETE) işlemlerinden çok daha fazlaysa (örneğin, raporlama veya analiz sistemleri).
  • Okuma performansını artırmak için veri fazlalığı tolere edilebilir.

Önceden Hesaplanmış Verilere İhtiyaç:

  • Toplamlar, ortalamalar veya diğer hesaplanmış değerler sıkça kullanılıyorsa, bu değerleri her seferinde hesaplamak yerine saklamak performans sağlar.

Uygulama veya Kullanıcı Deneyimi Gereksinimleri:

  • Uygulamanın basitliği veya kullanıcı deneyimi, performans veya geliştirme kolaylığı için denormalizasyonu gerektirebilir.
  • Örnek: Bir mobil uygulamada, kullanıcı profil bilgilerinin tek bir sorguda alınması gerekiyorsa.

Donanım veya Ölçeklendirme Kısıtlamaları:

  • Eğer veritabanı sunucusunun kaynakları sınırlıysa veya ölçeklendirme maliyetliyse, denormalizasyon daha az birleştirme işlemiyle performansı artırabilir.

Not: Denormalizasyon, yazma ağırlıklı sistemlerde (örneğin, sık güncelleme yapılan bir finans sistemi) veya veri bütünlüğünün kritik olduğu durumlarda dikkatle uygulanmalıdır, çünkü veri fazlalığı anomalilere yol açabilir.


Denormalizasyon Nasıl Uygulanmalıdır?

Denormalizasyon, stratejik ve kontrollü bir şekilde uygulanmalıdır. Aşağıdaki teknikler ve adımlar yaygın olarak kullanılır:

Türetik Verilerin Saklanması:

  • Hesaplanmış veya özet verileri (örneğin, toplam sipariş tutarı, kullanıcı puanı) ayrı sütunlarda saklayın.
  • Örnek: Bir Siparişler tablosunda her siparişin toplam tutarını hesaplayıp saklamak.

Tabloları Birleştirme:

  • Sık kullanılan birleştirme işlemlerini ortadan kaldırmak için ilişkili verileri tek bir tabloda bir araya getirin.
  • Örnek: Müşteriler ve Siparişler tablolarını birleştirerek müşteri bilgilerini sipariş tablosuna eklemek.

Önbelleğe Alma (Caching):

  • Sık erişilen sorgu sonuçlarını veya verileri önbellek tablolarında saklayın.
  • Örnek: Bir rapor için günlük satış toplamlarını ayrı bir tabloda tutmak.

Yinelenen Verilerin Eklenmesi:

  • Aynı veriyi birden fazla tabloda saklayarak birleştirme ihtiyacını azaltın.
  • Örnek: MüşteriAdı gibi sık kullanılan bir bilgiyi Siparişler tablosuna eklemek.

Dizin (Index) ve Materyalize Görünümler Kullanımı:

  • Denormalizasyona alternatif olarak, materyalize görünümler veya dizinler kullanarak performansı artırabilirsiniz.
  • Örnek: Sık sorgulanan bir birleştirme için materyalize bir görünüm oluşturmak.

Denormalizasyonun Kapsamını Sınırlama:

  • Yalnızca performans sorunlarının tespit edildiği alanlarda denormalizasyon uygulayın.
  • Tüm veritabanını denormalize etmek yerine, yalnızca kritik sorgular için optimize edin.

Adımlar:

  1. Performans Analizi: Veritabanı sorgularını analiz edin (örneğin, yavaş sorguları veya yüksek CPU kullanımı olan birleştirmeleri tespit edin).
  2. Gereksinim Belirleme: Hangi verilerin sık erişildiğini ve hangi sorguların optimize edilmesi gerektiğini belirleyin.
  3. Denormalizasyon Tasarımı: Hangi tabloların birleştirileceği, hangi verilerin kopyalanacağı veya önbelleğe alınacağı kararını verin.
  4. Veri Bütünlüğü Planı: Denormalize edilen verilerin güncellenmesi için tetikleyici (trigger), prosedür veya uygulama katmanı kontrolleri oluşturun.
  5. Test ve İzleme: Denormalizasyonun performans kazanımlarını test edin ve veri tutarlılığını izleyin.

Performans Kazanımları ile Veri Bütünlüğü Arasındaki Denge

Denormalizasyon, performans kazanımları sağlarken veri bütünlüğü risklerini artırır. Bu dengeyi kurmak için aşağıdaki stratejiler kullanılabilir:

Veri Bütünlüğünü Sağlamak için Kontroller:

  • Tetikleyiciler (Triggers): Denormalize edilen verilerin güncellenmesini otomatikleştirmek için tetikleyiciler kullanın. Örneğin, bir tabloda müşteri adı değiştiğinde, denormalize edilmiş tablolardaki kopyaları güncelleyin.
  • Saklı Prosedürler: Veri güncellemelerini merkezi bir prosedürle yöneterek tutarlılığı sağlayın.
  • Uygulama Katmanı Kontrolleri: Veritabanı seviyesinde kontrol zor olduğunda, uygulama kodunda veri tutarlılığını sağlayacak doğrulama mekanizmaları ekleyin.

Denormalizasyonu Sınırlı Tutma:

  • Yalnızca performans açısından kritik olan alanlarda denormalizasyon yapın. Örneğin, yalnızca en sık kullanılan raporlama sorguları için veri fazlalığı oluşturun.
  • Gereksiz denormalizasyon, bakım maliyetlerini artırır ve veri tutarsızlığı riskini yükseltir.

Okuma-Yazma Ayrımı:

  • Okuma ağırlıklı sorgular için denormalize edilmiş tablolar veya önbellekler kullanın, ancak yazma işlemleri için normalleştirilmiş yapıyı koruyun.
  • Örnek: Raporlama için denormalize edilmiş bir veri ambarı (data warehouse) kullanırken, işlem veritabanını (OLTP) normalleştirilmiş tutmak.

Düzenli Veri Senkronizasyonu:

  • Denormalize edilen verilerin periyodik olarak normalleştirilmiş kaynaklarla senkronize edildiğinden emin olun. Örneğin, bir ETL (Extract, Transform, Load) süreciyle veri güncellemelerini otomatikleştirin.

Dokümantasyon ve İzleme:

  • Denormalize edilen alanları ve bağımlılıkları belgeleyin. Hangi verilerin kopyalandığını ve nasıl güncellendiğini netleştirin.
  • Veri tutarsızlıklarını tespit etmek için izleme araçları kullanın.

Performans Testleri:

  • Denormalizasyonun sağladığı performans kazanımlarını ölçün (örneğin, sorgu süreleri, CPU kullanımı). Eğer kazanımlar küçükse, veri bütünlüğü riskleri ağır basabilir.

Gerçek Dünya Senaryoları ve Örnekler
Senaryo 1: E-Ticaret Platformu – Sık Erişilen Ürün Bilgileri

Problem:

  • Bir e-ticaret sitesinde, ürün detay sayfaları sıkça görüntüleniyor ve her görüntüleme için Ürünler, Kategoriler, Stok ve Fiyatlar tabloları arasında birleştirme yapılıyor.
  • Yoğun trafik saatlerinde, bu birleştirmeler veritabanını yavaşlatıyor ve kullanıcı deneyimini olumsuz etkiliyor.

Denormalizasyon Çözümü:

  • Ürünler tablosuna KategoriAdı, StokMiktarı ve Fiyat gibi sık erişilen bilgileri ekleyin.
  • Örnek:
    Normalleştirilmiş Yapı:
  • Ürünler: (ÜrünID, ÜrünAdı, KategoriID)
  • Kategoriler: (KategoriID, KategoriAdı)
  • Stok: (ÜrünID, StokMiktarı)
  • Fiyatlar: (ÜrünID, Fiyat) Denormalize Edilmiş Yapı:
  • Ürünler: (ÜrünID, ÜrünAdı, KategoriAdı, StokMiktarı, Fiyat)

Performans Kazanımı:

  • Ürün detay sorguları tek bir tablodan yapılır, birleştirme ihtiyacı ortadan kalkar.
  • Sorgu süreleri %50’ye kadar azalabilir, özellikle yüksek trafikli sitelerde kullanıcı deneyimi iyileşir.

Veri Bütünlüğü Yönetimi:

  • Kategoriler, Stok veya Fiyatlar tablolarında bir güncelleme olduğunda, Ürünler tablosundaki ilgili sütunları güncellemek için tetikleyiciler veya saklı prosedürler kullanılır.
  • Örnek Tetikleyici:
  CREATE TRIGGER UpdateUrunKategori
  AFTER UPDATE ON Kategoriler
  FOR EACH ROW
  UPDATE Ürünler
  SET KategoriAdı = NEW.KategoriAdı
  WHERE KategoriAdı = OLD.KategoriAdı;

Denge:

  • Performans artışı, kullanıcı deneyimi için kritik olduğundan veri fazlalığı tolere edilir.
  • Tetikleyiciler ve düzenli senkronizasyon ile veri tutarsızlığı riski en aza indirilir.

Senaryo 2: Raporlama Sistemi – Satış Raporları

Problem:

  • Bir perakende zinciri, günlük satış raporları için Siparişler, Müşteriler, Ürünler ve SiparişDetayları tablolarını birleştiren karmaşık sorgular kullanıyor.
  • Raporlar, yöneticiler için gerçek zamanlı değil, gecikmeli üretiliyor ve veritabanı performansını düşürüyor.

Denormalizasyon Çözümü:

  • Günlük satış verilerini özetleyen bir denormalize tablo (SatışRaporu) oluşturun.
  • Örnek:
    Normalleştirilmiş Yapı:
  • Siparişler: (SiparişID, MüşteriID, Tarih)
  • Müşteriler: (MüşteriID, MüşteriAdı)
  • SiparişDetayları: (SiparişID, ÜrünID, Miktar, Fiyat)
  • Ürünler: (ÜrünID, ÜrünAdı) Denormalize Edilmiş Yapı:
  • SatışRaporu: (Tarih, MüşteriAdı, ÜrünAdı, ToplamMiktar, ToplamTutar)
  • Bu tablo, bir ETL süreciyle her gece güncellenir.

Performans Kazanımı:

  • Rapor sorguları, birleştirme yerine tek bir tablodan çalışır, bu da sorgu sürelerini %70’e kadar azaltabilir.
  • Yöneticiler, gerçek zamanlıya yakın raporlar alabilir.

Veri Bütünlüğü Yönetimi:

  • SatışRaporu tablosu, yalnızca okuma amaçlıdır ve yazma işlemleri normalleştirilmiş tablolarda yapılır.
  • ETL süreci, veri tutarlılığını sağlamak için kaynak tablolardan doğru verileri çeker.
  • Örnek ETL Sorgusu:
  INSERT INTO SatışRaporu (Tarih, MüşteriAdı, ÜrünAdı, ToplamMiktar, ToplamTutar)
  SELECT s.Tarih, m.MüşteriAdı, u.ÜrünAdı, SUM(sd.Miktar), SUM(sd.Miktar * sd.Fiyat)
  FROM Siparişler s
  JOIN Müşteriler m ON s.MüşteriID = m.MüşteriID
  JOIN SiparişDetayları sd ON s.SiparişID = sd.SiparişID
  JOIN Ürünler u ON sd.ÜrünID = u.ÜrünID
  GROUP BY s.Tarih, m.MüşteriAdı, u.ÜrünAdı;

Denge:

  • Raporlama, okuma ağırlıklı olduğu için denormalizasyon idealdir.
  • Veri tutarlılığı, ETL sürecinin doğruluğuna bağlıdır; bu nedenle ETL işlemlerinin test edilmesi ve izlenmesi kritik önemdedir.

Senaryo 3: Sosyal Medya Platformu – Kullanıcı Profilleri

Problem:

  • Bir sosyal medya uygulamasında, kullanıcı profilleri (Kullanıcılar, Gönderiler, Takipçiler) sıkça sorgulanıyor ve her profil görüntülemesi birden fazla tabloyu birleştiriyor.
  • Yüksek kullanıcı trafiği, veritabanını yavaşlatıyor ve mobil uygulama yanıt sürelerini artırıyor.

Denormalizasyon Çözümü:

  • Kullanıcı profillerini önbelleğe alan bir denormalize tablo (KullanıcıProfilleri) oluşturun.
  • Örnek:
    Normalleştirilmiş Yapı:
  • Kullanıcılar: (KullanıcıID, Ad, Soyad, Eposta)
  • Gönderiler: (GönderiID, KullanıcıID, İçerik, Tarih)
  • Takipçiler: (KullanıcıID, TakipçiID) Denormalize Edilmiş Yapı:
  • KullanıcıProfilleri: (KullanıcıID, AdSoyad, GönderiSayısı, TakipçiSayısı, SonGönderi)
  • Bu tablo, kullanıcı profili her görüntülendiğinde hızlı erişim sağlar.

Performans Kazanımı:

  • Profil görüntüleme sorguları tek bir tablodan yapılır, birleştirme maliyeti ortadan kalkar.
  • Mobil uygulama yanıt süreleri %60’a kadar iyileşebilir.

Veri Bütünlüğü Yönetimi:

  • KullanıcıProfilleri tablosu, bir önbellek gibi çalışır ve periyodik olarak veya olay bazlı (örneğin, yeni gönderi eklendiğinde) güncellenir.
  • Olay bazlı güncelleme için tetikleyici:
  CREATE TRIGGER UpdateProfilGonderi
  AFTER INSERT ON Gönderiler
  FOR EACH ROW
  UPDATE KullanıcıProfilleri
  SET GönderiSayısı = GönderiSayısı + 1,
      SonGönderi = NEW.İçerik
  WHERE KullanıcıID = NEW.KullanıcıID;

Denge:

  • Kullanıcı deneyimi için hızlı yanıt süreleri kritik olduğundan, veri fazlalığı kabul edilir.
  • Önbellek tablosunun güncellenmesi, uygulama katmanında veya tetikleyicilerle yönetilir, böylece veri tutarsızlığı riski azalır.
Veri Bütünlüğü ve Kısıtlamalar
1. Varlık Bütünlüğü (Entity Integrity)
Tanım:
  • Varlık bütünlüğü, bir tablodaki her satırın benzersiz ve tanımlanabilir olmasını sağlar. Bu, genellikle birincil anahtar (primary key) veya benzersiz anahtar (unique key) kısıtlamalarıyla uygulanır.
  • Birincil anahtar, bir tablodaki her satırı benzersiz şekilde tanımlar ve NULL değer alamaz.
Neden Gerekli?
  • Satırların benzersizliğini garanti ederek veri tekrarını önler.
  • Veritabanında her kaydın net bir şekilde tanımlanmasını sağlar, böylece sorgular ve ilişkiler doğru çalışır.
SQL Örneği:
CREATE TABLE Musteriler (
    MusteriID INT PRIMARY KEY, -- Birincil anahtar: Benzersiz ve NULL olamaz
    Ad VARCHAR(50) NOT NULL,
    Soyad VARCHAR(50) NOT NULL
);

-- Başarılı ekleme
INSERT INTO Musteriler (MusteriID, Ad, Soyad) VALUES (1, 'Ali', 'Veli');

-- Hata: Aynı MusteriID ile ekleme yapılamaz (benzersizlik ihlali)
INSERT INTO Musteriler (MusteriID, Ad, Soyad) VALUES (1, 'Ayşe', 'Yılmaz');

-- Hata: MusteriID NULL olamaz (varlık bütünlüğü ihlali)
INSERT INTO Musteriler (Ad, Soyad) VALUES ('Ahmet', 'Kaya');
Önlenen Sorunlar:
  • Tekrarlanan Kayıtlar: Aynı birincil anahtar değeri ile birden fazla satır eklenmesini engeller.
  • Tanımlanamayan Kayıtlar: NULL birincil anahtar değerleri nedeniyle belirsiz satırların oluşmasını önler.

2. Referans Bütünlüğü (Referential Integrity)
Tanım:
  • Referans bütünlüğü, bir tablodaki yabancı anahtar (foreign key) değerlerinin, ilgili tablonun birincil anahtar veya benzersiz anahtar değerleriyle uyumlu olmasını sağlar.
  • Yabancı anahtar, bir tablodaki bir sütunun başka bir tablonun birincil anahtarına işaret etmesini sağlar ve bu ilişkiyi korumak için kısıtlamalar uygulanır.
Neden Gerekli?
  • Tablolar arasındaki ilişkilerin tutarlılığını korur.
  • Geçersiz veya “yetim” (orphaned) kayıtların oluşmasını engeller (örneğin, bir siparişin不存在的 bir müşteriye bağlı olması).
SQL Örneği:
CREATE TABLE Siparisler (
    SiparisID INT PRIMARY KEY,
    MusteriID INT,
    SiparisTarihi DATE,
    FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID) -- Referans bütünlüğü
);

-- Başarılı ekleme: MusteriID, Musteriler tablosunda mevcut
INSERT INTO Siparisler (SiparisID, MusteriID, SiparisTarihi) 
VALUES (1, 1, '2025-05-07');

-- Hata: MusteriID=999, Musteriler tablosunda yok (referans bütünlüğü ihlali)
INSERT INTO Siparisler (SiparisID, MusteriID, SiparisTarihi) 
VALUES (2, 999, '2025-05-07');
Referans Eylemleri (Referential Actions):

Yabancı anahtar ilişkilerinde, ana tablodaki bir kaydın güncellenmesi veya silinmesi durumunda, bağımlı tablodaki kayıtların nasıl etkileneceğini belirleyen eylemlerdir. SQL’de yaygın eylemler şunlardır:

CASCADE:

  • Ana tablodaki bir kaydın silinmesi veya güncellenmesi durumunda, bağımlı tablodaki ilgili kayıtlar da otomatik olarak silinir veya güncellenir.
  • Ne Zaman Kullanılır?:
    • Bağımlı kayıtların ana kayıt olmadan anlamsız olduğu durumlarda (örneğin, bir müşteriye bağlı siparişler).
    • Veri tutarlılığını otomatik olarak korumak için.
  • Örnek: CREATE TABLE Siparisler ( SiparisID INT PRIMARY KEY, MusteriID INT, FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID) ON DELETE CASCADE ON UPDATE CASCADE ); -- Musteriler tablosundan bir müşteri silindiğinde, ilgili siparişler de silinir DELETE FROM Musteriler WHERE MusteriID = 1; -- Siparisler tablosunda MusteriID=1 olan kayıtlar da silinir -- MusteriID güncellendiğinde, Siparisler tablosundaki MusteriID de güncellenir UPDATE Musteriler SET MusteriID = 100 WHERE MusteriID = 1;

SET NULL:

  • Ana tablodaki bir kaydın silinmesi veya güncellenmesi durumunda, bağımlı tablodaki yabancı anahtar değeri NULL olarak ayarlanır.
  • Ne Zaman Kullanılır?:
    • Yabancı anahtar sütununun NULL alması uygun olduğunda (isteğe bağlı ilişkiler).
    • Bağımlı kayıtların ana kayıt olmadan da anlamlı olabileceği durumlarda (örneğin, bir siparişin müşterisi bilinmeyebilir).
  • Örnek: CREATE TABLE Siparisler ( SiparisID INT PRIMARY KEY, MusteriID INT NULL, FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID) ON DELETE SET NULL ON UPDATE SET NULL ); -- Musteriler tablosundan bir müşteri silindiğinde, ilgili siparişlerin MusteriID'si NULL olur DELETE FROM Musteriler WHERE MusteriID = 1; -- Siparisler tablosunda MusteriID=1 olan kayıtlar MusteriID=NULL olur

RESTRICT:

  • Ana tablodaki bir kaydın silinmesi veya güncellenmesi, bağımlı tablodaki ilgili kayıtlar varsa engellenir.
  • Ne Zaman Kullanılır?:
    • Ana kaydın silinmesi veya güncellenmesinin bağımlı kayıtları etkilemesi istenmediğinde.
    • Veri kaybını önlemek için sıkı kontrol gerektiğinde (örneğin, bir departmanın silinmesi, çalışanlar varsa engellenir).
  • Örnek: CREATE TABLE Siparisler ( SiparisID INT PRIMARY KEY, MusteriID INT, FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID) ON DELETE RESTRICT ON UPDATE RESTRICT ); -- Hata: MusteriID=1, Siparisler tablosunda kullanıldığı için silinemez DELETE FROM Musteriler WHERE MusteriID = 1;

NO ACTION (varsayılan davranış):

  • RESTRICT ile benzerdir, ancak bazı veritabanlarında işlem sırası farklı olabilir (örneğin, işlem sonunda kontrol edilir).
  • Ne Zaman Kullanılır?: RESTRICT gibi durumlarda, ancak daha fazla esneklik gerektiğinde.

SET DEFAULT:

  • Ana tablodaki bir kaydın silinmesi veya güncellenmesi durumunda, bağımlı tablodaki yabancı anahtar varsayılan bir değere ayarlanır.
  • Ne Zaman Kullanılır?: Nadiren kullanılır, çünkü yabancı anahtar için uygun bir varsayılan değer tanımlanması zordur.
Referans Eylemlerinin Kullanım Senaryoları:
  • CASCADE: Bir e-ticaret sisteminde, bir müşteri hesabını sildiğinde, tüm siparişlerinin de silinmesi isteniyorsa.
  • SET NULL: Bir çalışanın bağlı olduğu departman silindiğinde, çalışanın departman bilgisinin NULL olması kabul edilebilirse.
  • RESTRICT: Bir okul veritabanında, bir dersin silinmesi, o derse kayıtlı öğrenciler varsa engellenmek isteniyorsa.
Önlenen Sorunlar:
  • Yetim Kayıtlar: Yabancı anahtarların geçersiz değerler (var olmayan birincil anahtarlar) almasını engeller.
  • Veri Tutarsızlığı: Tablolar arasındaki ilişkilerin bozulmasını önler.

3. Alan Kısıtlamaları (Domain Constraints)
Tanım:
  • Alan kısıtlamaları, bir sütunun alabileceği değerlerin türünü, aralığını veya biçimini sınırlandırır. Bu, veri doğruluğunu ve uygunluğunu sağlar.
  • Yaygın alan kısıtlamaları: NOT NULL, CHECK, DEFAULT, veri türü kısıtlamaları ve UNIQUE.
Neden Gerekli?
  • Verilerin belirli kurallara uygun olmasını sağlar (örneğin, yaşın negatif olmaması).
  • Uygulama seviyesinde doğrulama yükünü azaltır ve veritabanı seviyesinde tutarlılık sağlar.
SQL Örneği:
CREATE TABLE Calisanlar (
    CalisanID INT PRIMARY KEY,
    Ad VARCHAR(50) NOT NULL, -- NOT NULL: Ad boş olamaz
    Yas INT CHECK (Yas >= 18 AND Yas <= 65), -- CHECK: Yaş 18-65 aralığında olmalı
    Departman VARCHAR(50) DEFAULT 'Belirtilmemiş', -- DEFAULT: Varsayılan değer
    Email VARCHAR(100) UNIQUE -- UNIQUE: E-posta benzersiz olmalı
);

-- Başarılı ekleme
INSERT INTO Calisanlar (CalisanID, Ad, Yas, Email) 
VALUES (1, 'Ali', 30, 'ali@example.com');

-- Hata: Ad NULL olamaz
INSERT INTO Calisanlar (CalisanID, Yas, Email) 
VALUES (2, 25, 'ayse@example.com');

-- Hata: Yas 18-65 aralığında değil
INSERT INTO Calisanlar (CalisanID, Ad, Yas, Email) 
VALUES (3, 'Ayşe', 17, 'ayse@example.com');

-- Hata: E-posta zaten kullanılıyor
INSERT INTO Calisanlar (CalisanID, Ad, Yas, Email) 
VALUES (4, 'Ahmet', 40, 'ali@example.com');

-- Varsayılan değer kullanımı
INSERT INTO Calisanlar (CalisanID, Ad, Yas, Email) 
VALUES (5, 'Veli', 35, 'veli@example.com'); -- Departman: 'Belirtilmemiş'
Önlenen Sorunlar:
  • Geçersiz Veriler: Yaşın negatif olması veya e-postanın tekrarlanması gibi hataları önler.
  • Eksik Veriler: Zorunlu alanların (NOT NULL) boş bırakılmasını engeller.
  • Tutarlılık: Verilerin tanımlı kurallara uygun olmasını sağlar.

Referans Eylemlerinin Ne Zaman Kullanılacağına Dair Özet
EylemKullanım SenaryosuÖrnek Durum
CASCADEAna kaydın silinmesi/güncellenmesi bağımlı kayıtları da etkilemeli.Bir müşterinin silinmesiyle siparişlerinin de silinmesi.
SET NULLAna kaydın silinmesi/güncellenmesi durumunda bağımlı kayıtlar NULL olabilir.Bir departman silindiğinde, çalışanların departman bilgisinin NULL olması.
RESTRICTAna kaydın silinmesi/güncellenmesi, bağımlı kayıtlar varsa engellenmeli.Bir dersin silinmesi, kayıtlı öğrenciler varsa engellenir.
NO ACTIONRESTRICT ile benzer, ancak işlem sırası farklı olabilir.RESTRICT’e benzer, ancak daha esnek işlem sıraları için.
SET DEFAULTBağımlı kayıtların yabancı anahtarı varsayılan bir değere ayarlanmalı (nadir kullanılır).Bir kategorinin silinmesiyle, ürünlerin varsayılan bir kategoriye atanması.

Pratik Uygulama ve Dikkat Edilmesi Gerekenler

Performans Etkisi:

  • CASCADE ve SET NULL, ek işlemler (silme/güncelleme) gerektirdiğinden performansı etkileyebilir. Büyük veri kümelerinde dikkatli kullanılmalıdır.
  • RESTRICT, silme/güncelleme işlemlerini engelleyerek performansı etkilemez, ancak uygulama mantığında ek kontroller gerektirebilir.

Uygulama Gereksinimlerine Göre Seçim:

  • İş mantığına göre hangi eylemin uygun olduğuna karar verilmelidir. Örneğin, bir muhasebe sisteminde RESTRICT tercih edilerek veri kaybı önlenirken, bir sosyal medya uygulamasında CASCADE ile hızlı temizlik yapılabilir.

Dokümantasyon:

  • Hangi tablolarda hangi referans eylemlerinin kullanıldığı belgelenmelidir. Bu, bakım ve hata ayıklama süreçlerini kolaylaştırır.

Test ve Doğrulama:

  • Referans eylemlerinin doğru çalıştığından emin olmak için test senaryoları oluşturulmalıdır (örneğin, bir müşteri silindiğinde siparişlerin durumu kontrol edilmelidir).
Şema Tasarımı
Şema tasarım prensipleri ve Çok katmanlı şema yapıları
Şema Tasarım Prensipleri

Şema, bir veritabanındaki tablolar, sütunlar, ilişkiler, kısıtlamalar ve diğer yapısal bileşenlerin tanımlandığı bir yapıdır. Şema tasarımı, veritabanının iş gereksinimlerini karşılayacak şekilde düzenlenmesini sağlar. Temel şema tasarım prensipleri şunlardır:

Veri Bütünlüğü ve Tutarlılık:

  • Varlık Bütünlüğü: Her tablo, benzersiz bir birincil anahtar (primary key) ile tanımlanmalıdır. Bu, satırların benzersizliğini garanti eder.
  • Referans Bütünlüğü: Yabancı anahtarlar (foreign keys), ilişkili tablolar arasında tutarlılığı sağlar.
  • Alan Kısıtlamaları: Veri türleri, NOT NULL, CHECK ve DEFAULT gibi kısıtlamalar, verilerin doğruluğunu ve uygunluğunu korur.

Normalizasyon:

  • Veritabanı, genellikle 3NF (üçüncü normal form) veya BCNF seviyesinde normalize edilmelidir. Bu, veri fazlalığını (redundancy) azaltır ve ekleme, silme, güncelleme anomalilerini önler.
  • Örnek: Bir Müşteriler tablosunda müşteri bilgileri ayrı, Siparişler tablosunda sipariş bilgileri ayrı tutulur.

Performans Optimizasyonu:

  • Normalizasyon, veri bütünlüğünü sağlasa da, aşırı normalizasyon performans sorunlarına yol açabilir. Bu nedenle, denormalizasyon stratejik olarak uygulanabilir (örneğin, sık sorgulanan verileri birleştirme işlemini azaltmak için).
  • Dizinler (indexes), sorgu performansını artırmak için kritik öneme sahiptir, ancak yazma işlemlerini yavaşlatabilir.

Esneklik ve Ölçeklenebilirlik:

  • Şema, gelecekteki değişikliklere (örneğin, yeni özellikler veya veri türleri ekleme) uyum sağlayacak şekilde tasarlanmalıdır.
  • Büyük ölçekli sistemlerde, şema modüler olmalı ve farklı iş birimlerine veya modüllere ayrılabilmelidir.

Anlaşılırlık ve Bakım Kolaylığı:

  • Tablo ve sütun isimleri, iş mantığını yansıtacak şekilde anlamlı ve tutarlı olmalıdır (örneğin, MusteriID yerine CustomerID gibi standart isimlendirme).
  • Şema dokümantasyonu, tabloların amacı, ilişkiler ve kısıtlamalar hakkında net bilgiler içermelidir.

Güvenlik ve Erişim Kontrolü:

  • Şema, veri erişimini kısıtlamak için roller ve izinlerle (permissions) yapılandırılmalıdır.
  • Hassas veriler (örneğin, kişisel bilgiler) ayrı tablolarda veya şifrelenmiş olarak saklanabilir.

Veri Türü ve Depolama Optimizasyonu:

  • Her sütun, uygun veri türüyle tanımlanmalıdır (örneğin, tarih için DATE, sayılar için INT veya DECIMAL).
  • Depolama maliyetlerini azaltmak için veri türleri optimize edilmelidir (örneğin, küçük sayılar için SMALLINT yerine INT kullanmaktan kaçının).

Çok Katmanlı Şema Yapıları

Çok katmanlı şema yapıları, veritabanı tasarımını kavramsal, mantıksal ve fiziksel seviyelerde organize etmek için kullanılan bir yaklaşımdır. Bu yapı, veritabanı tasarımını daha anlaşılır ve yönetilebilir hale getirir. Üç temel katman şunlardır:

Kavramsal Şema (Conceptual Schema):

  • Tanım: Veritabanının yüksek seviyeli, iş odaklı bir modelidir. İş gereksinimlerini ve varlık ilişkilerini (entities and relationships) tanımlar.
  • Amaç: İş mantığını soyut bir şekilde ifade eder, teknik detaylara girmez.
  • Örnek: Bir e-ticaret sistemi için kavramsal şema, Müşteriler, Siparişler, Ürünler gibi varlıkları ve aralarındaki ilişkileri (örneğin, “bir müşteri birden fazla sipariş verebilir”) tanımlar.
  • Araçlar: ER (Entity-Relationship) diyagramları genellikle kullanılır.
  • Örnek ER Diyagramı:
    [Müşteriler] ---1:N---> [Siparişler] ---N:M---> [Ürünler]

Mantıksal Şema (Logical Schema):

  • Tanım: Kavramsal şemayı, belirli bir veritabanı yönetim sistemi (DBMS) için uygulanabilir bir yapıya dönüştürür. Tablolar, sütunlar, veri türleri, birincil/yabancı anahtarlar ve kısıtlamalar tanımlanır.
  • Amaç: Veritabanının yapısını, DBMS’ye özgü olmadan soyut bir şekilde tanımlar.
  • Örnek: Müşteriler tablosu için MusteriID (INT, PRIMARY KEY), Ad (VARCHAR), Siparişler tablosu için SiparisID (INT, PRIMARY KEY), MusteriID (FOREIGN KEY) gibi tanımlar.
  • SQL Örneği: CREATE TABLE Musteriler ( MusteriID INT PRIMARY KEY, Ad VARCHAR(50) NOT NULL, Soyad VARCHAR(50) NOT NULL ); CREATE TABLE Siparisler ( SiparisID INT PRIMARY KEY, MusteriID INT, SiparisTarihi DATE, FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID) );

Fiziksel Şema (Physical Schema):

  • Tanım: Veritabanının fiziksel depolama yapısını tanımlar. Dizinler, bölümleme (partitioning), dosya grupları, depolama motorları ve performans optimizasyonları bu katmanda belirlenir.
  • Amaç: Veritabanının performansını, ölçeklenebilirliğini ve depolama verimliliğini optimize eder.
  • Örnek: Musteriler tablosu için bir INDEX oluşturma, tabloyu yıllara göre bölümleme veya belirli bir depolama motoru (örneğin, InnoDB veya MyISAM) seçme.
  • SQL Örneği: CREATE INDEX idx_musteri_ad ON Musteriler(Ad); -- Performans için dizin CREATE TABLE Siparisler ( SiparisID INT PRIMARY KEY, MusteriID INT, SiparisTarihi DATE, FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID) ) PARTITION BY RANGE (YEAR(SiparisTarihi)) ( PARTITION p2023 VALUES LESS THAN (2024), PARTITION p2024 VALUES LESS THAN (2025), PARTITION p2025 VALUES LESS THAN (2026) );
Çok Katmanlı Şema Yapısının Avantajları:
  • Soyutlama: Kavramsal katman, iş mantığını teknik detaylardan ayırır.
  • Esneklik: Mantıksal şema, farklı DBMS’lere uyarlanabilir.
  • Optimizasyon: Fiziksel şema, performansı ve depolamayı optimize eder.
  • Bakım Kolaylığı: Her katman ayrı ayrı yönetilebilir, değişiklikler daha kolay uygulanır.

Büyük Ölçekli Veritabanında Şema Organizasyonu

Büyük ölçekli veritabanları (örneğin, milyonlarca kaydı veya terabaytlarca veriyi yöneten sistemler), yüksek trafik, karmaşık iş mantığı ve ölçeklenebilirlik gereksinimleriyle karşı karşıyadır. Bu tür sistemlerde şema organizasyonu, aşağıdaki prensipler ve uygulamalar doğrultusunda yapılmalıdır:

1. Modüler ve İşlevsel Ayrım
  • Modüler Tablolar: Veritabanını işlevsel modüllere ayırın (örneğin, müşteri yönetimi, sipariş yönetimi, envanter yönetimi).
  • Şema Ayrımı: Büyük sistemlerde, her modül için ayrı bir şema (schema) veya veritabanı kullanılabilir. Örneğin:
  • crm şeması: Müşteri bilgileri ve iletişim.
  • orders şeması: Siparişler ve ödemeler.
  • inventory şeması: Ürün ve stok bilgileri.
  • SQL Örneği:
  CREATE SCHEMA crm;
  CREATE TABLE crm.Musteriler (
      MusteriID INT PRIMARY KEY,
      Ad VARCHAR(50)
  );

  CREATE SCHEMA orders;
  CREATE TABLE orders.Siparisler (
      SiparisID INT PRIMARY KEY,
      MusteriID INT,
      FOREIGN KEY (MusteriID) REFERENCES crm.Musteriler(MusteriID)
  );
2. Normalizasyon ve Denormalizasyon Dengesi
  • Normalizasyon: Çekirdek işlem veritabanları (OLTP) için genellikle 3NF seviyesinde normalizasyon tercih edilir. Bu, veri tutarlılığını ve yazma işlemlerini optimize eder.
  • Denormalizasyon: Raporlama veya analitik sistemler (OLAP) için denormalize edilmiş tablolar veya veri ambarları (data warehouses) kullanılır. Örneğin, sık erişilen müşteri ve sipariş bilgilerini birleştiren bir tablo.
  • Örnek: Bir e-ticaret sisteminde, SiparisRaporu tablosu denormalize edilerek müşteri adı ve sipariş toplamı gibi bilgiler tek bir tabloda saklanabilir:
  CREATE TABLE SiparisRaporu (
      SiparisID INT,
      MusteriAd VARCHAR(100),
      ToplamTutar DECIMAL(10,2),
      SiparisTarihi DATE
  );
3. Bölümleme (Partitioning) ve Sharding
  • Bölümleme: Büyük tablolar, mantıksal parçalara bölünerek performans artırılır. Örneğin, Siparisler tablosu yıllara veya bölgelere göre bölünür.
  • SQL Örneği:
    sql CREATE TABLE Siparisler ( SiparisID INT, MusteriID INT, SiparisTarihi DATE ) PARTITION BY RANGE (YEAR(SiparisTarihi)) ( PARTITION p2023 VALUES LESS THAN (2024), PARTITION p2024 VALUES LESS THAN (2025) );
  • Sharding: Veriler fiziksel olarak farklı veritabanı sunucularına dağıtılır (örneğin, coğrafi bölgelere göre). Bu, ölçeklenebilirliği artırır, ancak şema yönetimini karmaşıklaştırır.
  • Örnek: Avrupa müşterileri için bir veritabanı, Asya müşterileri için başka bir veritabanı.
4. Dizinleme Stratejisi
  • Sık sorgulanan sütunlar için dizinler oluşturun, ancak aşırı dizinleme yazma performansını düşürebilir.
  • Örnek:
  CREATE INDEX idx_siparis_tarihi ON Siparisler(SiparisTarihi);
  CREATE INDEX idx_musteri_ad ON Musteriler(Ad);
  • Kapsayıcı Dizinler (Covering Indexes): Sorguların tamamını karşılayacak dizinler oluşturun.
  CREATE INDEX idx_siparis_musteri ON Siparisler(MusteriID, SiparisTarihi);
5. Veri Türü ve Depolama Optimizasyonu
  • Sütunlar için uygun veri türleri seçin (örneğin, BIGINT yerine INT veya VARCHAR(50) yerine CHAR(10)).
  • Büyük veri kümeleri için sıkıştırma (compression) veya columnar storage gibi teknolojiler kullanın (örneğin, PostgreSQL’de TOAST veya Snowflake’ta columnar storage).
6. Güvenlik ve Erişim Kontrolü
  • Her şema veya tablo için uygun izinler tanımlayın.
  • Hassas verileri (örneğin, kredi kartı bilgileri) şifrelenmiş sütunlarda saklayın.
  • SQL Örneği:
  GRANT SELECT, INSERT ON crm.Musteriler TO 'crm_user';
  REVOKE DELETE ON orders.Siparisler FROM 'public';
7. Veri Arşivleme ve Temizleme
  • Eski verileri arşivlemek için ayrı tablolar veya veritabanları kullanın. Örneğin, 5 yıldan eski siparişler bir SiparisArsiv tablosuna taşınabilir.
  • SQL Örneği:
  INSERT INTO SiparisArsiv
  SELECT * FROM Siparisler WHERE SiparisTarihi < '2020-01-01';
  DELETE FROM Siparisler WHERE SiparisTarihi < '2020-01-01';
8. Şema Versiyonlama ve Göç (Migration)
  • Büyük ölçekli sistemlerde, şema değişiklikleri (örneğin, yeni sütun ekleme) dikkatle yönetilmelidir. Şema versiyonlama araçları (örneğin, Flyway, Liquibase) kullanılabilir.
  • Örnek: Yeni bir sütun ekleme:
  ALTER TABLE Musteriler ADD Telefon VARCHAR(15);
9. Performans İzleme ve Optimizasyon
  • Sorgu performansını izlemek için araçlar (örneğin, PostgreSQL’de EXPLAIN ANALYZE, Oracle’da AWR raporları) kullanın.
  • Yavaş sorgular için dizin ekleme, bölümleme veya denormalizasyon gibi çözümler uygulayın.
10. Dokümantasyon ve Standartlar
  • Her tablo, sütun ve ilişkinin amacı dokümante edilmelidir.
  • İsimlendirme standartları tutarlı olmalıdır (örneğin, ID yerine MusteriID, tablo isimleri çoğul: Musteriler, Siparisler).
  • Örnek Dokümantasyon:
  Tablo: Musteriler
  - MusteriID (INT, PRIMARY KEY): Benzersiz müşteri kimliği
  - Ad (VARCHAR): Müşterinin adı
  - Soyad (VARCHAR): Müşterinin soyadı
  İlişkiler: Siparisler.MusteriID ile 1:N ilişkisi

Büyük Ölçekli Veritabanında Şema Organizasyonu için Örnek

Bir e-ticaret platformu için büyük ölçekli bir veritabanı şema organizasyonu şu şekilde olabilir:

Şema Ayrımı:

  • crm: Müşteri bilgileri, iletişim geçmişi, destek talepleri.
  • orders: Siparişler, ödemeler, iade işlemleri.
  • inventory: Ürünler, stok, tedarikçiler.
  • analytics: Raporlama ve analitik veriler (denormalize edilmiş).

Tablo Örneği:

   -- CRM Şeması
   CREATE SCHEMA crm;
   CREATE TABLE crm.Musteriler (
       MusteriID BIGINT PRIMARY KEY,
       Ad VARCHAR(50) NOT NULL,
       Soyad VARCHAR(50) NOT NULL,
       Email VARCHAR(100) UNIQUE,
       KayitTarihi DATE DEFAULT CURRENT_DATE
   );

   -- Orders Şeması
   CREATE SCHEMA orders;
   CREATE TABLE orders.Siparisler (
       SiparisID BIGINT PRIMARY KEY,
       MusteriID BIGINT,
       SiparisTarihi DATE,
       ToplamTutar DECIMAL(10,2),
       FOREIGN KEY (MusteriID) REFERENCES crm.Musteriler(MusteriID) ON DELETE SET NULL
   ) PARTITION BY RANGE (SiparisTarihi);

   -- Inventory Şeması
   CREATE SCHEMA inventory;
   CREATE TABLE inventory.Urunler (
       UrunID BIGINT PRIMARY KEY,
       UrunAdi VARCHAR(100),
       KategoriID INT,
       StokMiktari INT CHECK (StokMiktari >= 0)
   );

   -- Analytics Şeması (Denormalize)
   CREATE SCHEMA analytics;
   CREATE TABLE analytics.SiparisRaporu (
       SiparisID BIGINT,
       MusteriAd VARCHAR(100),
       UrunAdi VARCHAR(100),
       ToplamTutar DECIMAL(10,2),
       SiparisTarihi DATE
   );

Performans Optimizasyonları:

  • Siparisler tablosu için tarih bazlı bölümleme.
  • Musteriler.Email ve Siparisler.SiparisTarihi için dizinler.
  • SiparisRaporu tablosu, ETL süreciyle periyodik olarak güncellenir.

Güvenlik:

  • crm.Musteriler tablosuna yalnızca CRM ekibi erişebilir.
  • analytics şemasına yalnızca raporlama araçları erişir.

Arşivleme:

  • 3 yıldan eski siparişler, orders.SiparisArsiv tablosuna taşınır.
Şema versiyonlama ve evrim
Şema Versiyonlama ve Evrimi Nedir?
  • Şema Versiyonlama: Veritabanı şemasının (tablolar, sütunlar, kısıtlamalar, dizinler vb.) her bir durumunun bir sürüm numarası veya kimliğiyle takip edilmesidir. Her değişiklik, şemanın yeni bir versiyonunu oluşturur.
  • Şema Evrimi: Zamanla iş gereksinimlerine veya teknik ihtiyaçlara bağlı olarak şemada yapılan değişikliklerdir. Örneğin, yeni bir sütun ekleme, bir tabloyu yeniden yapılandırma veya kısıtlamaları güncelleme.

Neden Önemli?

  • Canlı sistemlerde, şema değişiklikleri yanlış uygulanırsa veri kaybına, uygulama hatalarına veya kesintilere neden olabilir.
  • Şema versiyonlama, değişikliklerin izlenebilir, tekrarlanabilir ve geri alınabilir olmasını sağlar.
  • Büyük ekiplerde, birden fazla geliştiricinin aynı şema üzerinde çalışması durumunda çakışmaları önler.

Şema Versiyonlama ve Evrimi için En İyi Pratikler

Şema Değişikliklerini Kod Olarak Yönetin (Database as Code):

  • Şema değişikliklerini SQL betikleri (scripts) veya yapılandırma dosyaları olarak saklayın ve bunları bir sürüm kontrol sistemine (örneğin, Git) entegre edin.
  • Her değişiklik, bir migration (göç) dosyası olarak tanımlanır ve sırasıyla uygulanır.
  • Örnek: Bir sütun ekleme için migration dosyası:
    sql -- migration_20250507_add_email.sql ALTER TABLE Musteriler ADD Email VARCHAR(100);

Migration Araçları Kullanın:

  • Şema değişikliklerini otomatikleştirmek ve yönetmek için migration araçları kullanın. Popüler araçlar:
    • Flyway: SQL veya Java tabanlı migration’lar için.
    • Liquibase: XML, YAML veya SQL ile şema değişikliklerini tanımlar.
    • Alembic: Python tabanlı, özellikle SQLAlchemy ile kullanılır.
  • Bu araçlar, şema değişikliklerini sıralı bir şekilde uygular, versiyonları takip eder ve çakışmaları önler.
  • Örnek (Flyway): -- V1__create_musteriler.sql CREATE TABLE Musteriler ( MusteriID INT PRIMARY KEY, Ad VARCHAR(50) ); -- V2__add_email.sql ALTER TABLE Musteriler ADD Email VARCHAR(100);

Artımlı ve Geri Alınabilir Değişiklikler:

  • Her migration, küçük ve artımlı değişiklikler içermeli. Büyük çaplı yeniden yapılandırmalar yerine küçük adımlarla ilerleyin.
  • Her migration için bir geri alma (rollback) betiği hazırlayın. Örneğin: -- Uygulama (up) ALTER TABLE Musteriler ADD Telefon VARCHAR(15); -- Geri alma (down) ALTER TABLE Musteriler DROP COLUMN Telefon;
  • Geri alma betikleri, özellikle test ortamlarında veya hata durumlarında kullanışlıdır.

Şema Versiyonlarını Tutarlı Şekilde Numaralandırın:

  • Migration dosyalarına sıralı ve benzersiz bir kimlik verin (örneğin, V1, V2 veya zaman damgası: 202505071200).
  • Zaman damgaları, çakışmaları önlemek için özellikle büyük ekiplerde kullanışlıdır.
  • Örnek: 20250507_01_add_email.sql, 20250507_02_add_index.sql.

Değişiklikleri Dokümante Edin:

  • Her migration dosyasının amacı, hangi tabloyu/sütunu etkilediği ve iş mantığına olan etkisi dokümante edilmelidir.
  • Dokümantasyon, şema değişikliklerinin neden yapıldığını ve nasıl çalıştığını anlamayı kolaylaştırır.
  • Örnek Dokümantasyon:
    Migration: V2__add_email.sql Tarih: 2025-05-07 Amaç: Musteriler tablosuna e-posta alanı eklemek Etkilenen Tablo: Musteriler Değişiklik: Yeni sütun Email (VARCHAR(100)) eklendi

Test Ortamlarında Değişiklikleri Doğrulayın:

  • Şema değişikliklerini önce bir geliştirme veya test ortamında uygulayın.
  • Test ortamı, canlı sistemin bir kopyasını içermeli ve gerçek veriyle benzer senaryolar test edilmelidir.
  • Örnek Test Senaryoları:
    • Yeni sütun eklenmesi mevcut verileri etkiliyor mu?
    • Yabancı anahtar eklenmesi veri bütünlüğünü bozuyor mu?
    • Sorgu performansı nasıl etkileniyor?

Veri Bütünlüğünü Koruyun:

  • Şema değişiklikleri, mevcut verilerin tutarlılığını bozmamalıdır. Örneğin:
    • Yeni bir NOT NULL sütun ekleniyorsa, mevcut satırlara varsayılan bir değer atanmalıdır.
    • Yabancı anahtar ekleniyorsa, mevcut verilerin bu kısıtlamaya uygun olduğundan emin olun.
  • Örnek:
    sql ALTER TABLE Musteriler ADD Durum VARCHAR(20) NOT NULL DEFAULT 'Aktif';

Performans Etkilerini Değerlendirin:

  • Büyük ölçekli tablolarda şema değişiklikleri (örneğin, sütun ekleme, dizin oluşturma) uzun sürebilir ve tabloya erişimi kilitleyebilir.
  • Performans etkisini en aza indirmek için:
    • Değişiklikleri düşük trafik saatlerinde uygulayın.
    • Büyük tablolarda çevrimiçi (online) şema değişikliklerini destekleyen DBMS özelliklerini kullanın (örneğin, PostgreSQL’de CONCURRENTLY ile dizin oluşturma).
  • Örnek:
    sql CREATE INDEX CONCURRENTLY idx_musteri_email ON Musteriler(Email);

Şema Değişikliklerini Otomatikleştirin:

  • CI/CD (Continuous Integration/Continuous Deployment) pipeline’larına migration araçlarını entegre edin.
  • Her yeni kod dağıtımıyla birlikte şema değişiklikleri otomatik olarak uygulanır.
  • Örnek: GitHub Actions ile Flyway entegrasyonu:
    yaml name: Deploy Database Migrations on: push jobs: migrate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Run Flyway Migrations run: flyway migrate -url=jdbc:postgresql://db:5432/mydb -user=user -password=pass

Geri Dönüş Planı (Rollback Strategy):

  • Her şema değişikliği için bir geri dönüş planı oluşturun. Bu, hata durumunda sistemi önceki duruma döndürmeyi kolaylaştırır.
  • Geri dönüş için:
  • Veritabanı yedekleri alın.
  • Geri alma betiklerini hazır tutun.
  • Kritik değişikliklerde, önce bir snapshot (örneğin, AWS RDS snapshot) alın.

Canlı Sistemlerde Şema Değişikliklerini Güvenli Bir Şekilde Uygulama

Canlı sistemlerde şema değişiklikleri, kullanıcı deneyimini veya veri bütünlüğünü etkilemeden uygulanmalıdır. Aşağıda, bu süreci güvenli bir şekilde yönetmek için adımlar ve teknikler sunulmaktadır:

1. Planlama ve Hazırlık
  • Değişiklik Analizi:
  • Değişikliğin kapsamını (tablolar, veriler, sorgular) ve potansiyel risklerini değerlendirin.
  • Örneğin, bir sütun tipi değişikliği (VARCHAR’dan INT’e) veri kaybına neden olabilir mi?
  • Yedek Alma:
  • Değişiklikten önce veritabanının tam bir yedeğini alın.
  • Örnek: PostgreSQL’de:
    bash pg_dump -U user -d mydb > backup_20250507.sql
  • Test Ortamında Deneme:
  • Canlı sistemin bir kopyasında (staging) değişiklikleri test edin.
  • Gerçek veriyle benzer senaryoları simüle edin (örneğin, yüksek trafik, büyük veri kümeleri).
  • Düşük Trafik Zamanlaması:
  • Değişiklikleri, sistemin en az kullanıldığı saatlerde uygulayın (örneğin, gece saatleri).
2. Güvenli Şema Değişiklik Türleri

Bazı şema değişiklikleri, canlı sistemlerde daha az risklidir ve doğrudan uygulanabilir. Diğerleri ise özel stratejiler gerektirir. İşte yaygın değişiklik türleri ve güvenli uygulama yöntemleri:

  • Düşük Riskli Değişiklikler (Hemen Uygulanabilir):
  • Yeni tablo veya sütun ekleme.
  • Yeni dizin oluşturma (tercihen CONCURRENTLY).
  • Varsayılan değer ekleme.
  • Örnek: ALTER TABLE Musteriler ADD YeniSutun VARCHAR(50); CREATE INDEX CONCURRENTLY idx_yeni_sutun ON Musteriler(YeniSutun);
  • Orta Riskli Değişiklikler (Dikkat Gerektirir):
  • Sütun tipini değiştirme (örneğin, VARCHAR(50)’dan VARCHAR(100)’e).
  • Kısıtlamalar ekleme (örneğin, NOT NULL, FOREIGN KEY).
  • Strateji: Mevcut verilerin yeni kısıtlamalara uygun olduğunu doğrulayın ve geçici tablolar veya veri dönüştürme betikleri kullanın.
  • Örnek (NOT NULL ekleme): -- Mevcut verilere varsayılan değer ata UPDATE Musteriler SET YeniSutun = 'Bilinmiyor' WHERE YeniSutun IS NULL; ALTER TABLE Musteriler ALTER COLUMN YeniSutun SET NOT NULL;
  • Yüksek Riskli Değişiklikler (Özel Stratejiler Gerektirir):
  • Sütun silme, tablo yeniden yapılandırma, büyük tablolarda dizin kaldırma.
  • Strateji: Sıfır kesinti (zero-downtime) teknikleri kullanın (aşağıda detaylı açıklanmıştır).
3. Sıfır Kesinti (Zero-Downtime) Şema Değişiklikleri

Büyük ölçekli veya 7/24 çalışan sistemlerde, şema değişiklikleri sistem kesintisi olmadan uygulanmalıdır. Yaygın sıfır kesinti stratejileri:

  • Geçici Sütun/Tablo Kullanımı:
  • Yeni bir sütun veya tablo oluşturun, verileri senkronize edin, ardından eski yapıyı kaldırın.
  • Örnek: Musteriler tablosunda Ad sütununu VARCHAR(50)’dan TEXT’e dönüştürme: -- 1. Yeni bir sütun ekle ALTER TABLE Musteriler ADD AdYeni TEXT; -- 2. Verileri kopyala UPDATE Musteriler SET AdYeni = Ad; -- 3. Eski sütunu kaldır ve yeni sütunu yeniden adlandır ALTER TABLE Musteriler DROP COLUMN Ad; ALTER TABLE Musteriler RENAME COLUMN AdYeni TO Ad;
  • Tetikleyici ile Senkronizasyon:
  • Yeni bir tablo veya sütun oluştururken, eski ve yeni yapılar arasında verileri senkronize etmek için tetikleyiciler kullanın.
  • Örnek: Yeni bir tabloya geçiş: -- Yeni tablo CREATE TABLE MusterilerYeni ( MusteriID INT PRIMARY KEY, Ad TEXT ); -- Tetikleyici: Eski tablodaki değişiklikleri yeniye yansıt CREATE TRIGGER sync_musteriler AFTER INSERT OR UPDATE ON Musteriler FOR EACH ROW EXECUTE FUNCTION sync_musteriler_to_new(); -- Verileri kopyala INSERT INTO MusterilerYeni SELECT MusteriID, Ad FROM Musteriler; -- Uygulamayı yeni tabloya yönlendir ve eskiyi kaldır
  • Gölge Tablo (Shadow Table):
  • Yeni bir tablo oluşturun, verileri kopyalayın, uygulamayı yeni tabloya yönlendirin ve eski tabloyu kaldırın.
  • Bu yöntem, büyük yeniden yapılandırmalarda kullanılır.
  • Çevrimiçi Dizin Oluşturma:
  • Dizin oluştururken tabloyu kilitlemekten kaçınmak için CONCURRENTLY kullanın.
  • Örnek:
    sql CREATE INDEX CONCURRENTLY idx_musteri_email ON Musteriler(Email);
4. Uygulama ve İzleme
  • Değişiklikleri Uygulama:
  • Migration aracını çalıştırarak değişiklikleri uygulayın (örneğin, flyway migrate).
  • Küçük değişiklikleri gruplar halinde uygulayın, her gruptan sonra sistemi test edin.
  • İzleme:
  • Değişiklik sonrası veritabanı performansını (örneğin, sorgu süreleri, kilitlenme) izleyin.
  • Hataları yakalamak için loglama ve izleme araçları kullanın (örneğin, PostgreSQL logları, New Relic).
  • Hata Yönetimi:
  • Hata durumunda, geri alma betiklerini çalıştırın veya yedeği geri yükleyin.
5. İletişim ve Koordinasyon
  • Değişikliklerden etkilenecek ekipleri (örneğin, geliştiriciler, operasyon ekibi) önceden bilgilendirin.
  • Değişiklik zamanlamasını ve etkilerini tüm paydaşlarla paylaşın.
  • Örnek: Değişiklik öncesi bir duyuru:
  Başlık: Veritabanı Şema Güncellemesi
  Tarih: 2025-05-07 02:00
  Etkilenen Sistem: Musteriler Tablosu
  Değişiklik: Yeni Email sütunu eklenmesi
  Tahmini Süre: 15 dakika
  Geri Dönüş Planı: Yedek geri yükleme
6. Post-Deployment Doğrulama
  • Değişiklik sonrası, uygulamanın doğru çalıştığını ve veri bütünlüğünün korunduğunu doğrulayın.
  • Örnek kontroller:
  • Yeni sütunun beklendiği gibi çalıştığını test edin.
  • İlişkili sorguların performansını kontrol edin.
  • Veri tutarlılığını doğrulamak için örnek sorgular çalıştırın:
    sql SELECT COUNT(*) FROM Musteriler WHERE Email IS NULL;

Gerçek Dünya Örneği

Bir e-ticaret platformunda yeni bir müşteri iletişim özelliği eklemek için şema değişikliği gerektiğini varsayalım. Musteriler tablosuna Telefon ve IletisimTercihi sütunları eklenmeli.

Adımlar:

Migration Dosyası Oluşturma:

   -- V20250507_01_add_contact_info.sql
   ALTER TABLE Musteriler ADD Telefon VARCHAR(15);
   ALTER TABLE Musteriler ADD IletisimTercihi VARCHAR(20) DEFAULT 'Eposta';

Test Ortamında Uygulama:

  • Test veritabanında migration’ı çalıştırın:
    bash flyway migrate -url=jdbc:postgresql://test-db:5432/mydb
  • Uygulamanın yeni sütunlarla çalıştığını doğrulayın.

Canlı Sistemde Uygulama:

  • Düşük trafik saatinde (örneğin, 02:00) yedek alın:
    bash pg_dump -U user -d mydb > backup_20250507.sql
  • Migration’ı uygulayın:
    bash flyway migrate -url=jdbc:postgresql://prod-db:5432/mydb

Doğrulama:

  • Yeni sütunların eklendiğini kontrol edin:
    sql SELECT Telefon, IletisimTercihi FROM Musteriler LIMIT 10;
  • Uygulamanın doğru çalıştığını test edin.

Geri Dönüş Planı:

  • Hata durumunda, sütunları kaldırın:
    sql ALTER TABLE Musteriler DROP COLUMN Telefon; ALTER TABLE Musteriler DROP COLUMN IletisimTercihi;
  • Veya yedeği geri yükleyin:
    bash psql -U user -d mydb < backup_20250507.sql
Modelleme Yöntemleri
ER (Entity-Relationship) Modelleme
ER Modellemede Temel Kavramlar
1. Varlıklar (Entities)
  • Tanım: Gerçek dünyada benzersiz bir kimliğe sahip olan ve veritabanında saklanması gereken nesnelerdir. Varlıklar, bir tabloya karşılık gelir ve her varlık örneği bir satır olarak temsil edilir.
  • Türleri:
  • Güçlü Varlık (Strong Entity): Benzersiz bir birincil anahtara sahip olan varlıklar (örneğin, Müşteri, Ürün).
  • Zayıf Varlık (Weak Entity): Kendi başına benzersiz bir kimliği olmayan ve başka bir güçlü varlığa bağlı olan varlıklar (örneğin, bir siparişin detayları).
  • Özellikler (Attributes):
  • Varlıkların özelliklerini tanımlar (örneğin, Müşteri için Ad, Soyad, Email).
  • Türleri: Basit (atomik), bileşik (örneğin, Adres içinde Şehir, PostaKodu), çok değerli (örneğin, TelefonNumaraları), türetilmiş (örneğin, Yaş doğum tarihinden hesaplanır).
  • Temsil: ER diyagramında dikdörtgen ile gösterilir.
2. İlişkiler (Relationships)
  • Tanım: Varlıklar arasındaki bağlantıları ifade eder. İlişkiler, veritabanında yabancı anahtarlar (foreign keys) ile uygulanır.
  • Türleri:
  • Bir-tek (1:1): Bir varlığın bir örneği, diğer varlığın yalnızca bir örneğiyle ilişkilidir (örneğin, bir Kullanıcı bir Profil ile).
  • Bir-çok (1:N): Bir varlığın bir örneği, diğer varlığın birden fazla örneğiyle ilişkilidir (örneğin, bir Müşteri birden fazla Sipariş verebilir).
  • Çok-çok (N:M): Her iki varlığın birden fazla örneği birbirine bağlanabilir (örneğin, Sipariş ve Ürün arasında). Bu, bir ara tablo (junction table) ile uygulanır.
  • Temsil: ER diyagramında eşkenar dörtgen (diamond) veya doğrudan çizgilerle gösterilir.
3. Kardinalite Kısıtlamaları (Cardinality Constraints)
  • Tanım: İlişkilerde, bir varlığın diğer varlıkla kaç örneğe bağlanabileceğini belirtir. Kardinalite, ilişkilerin doğasını ve veri bütünlüğünü tanımlar.
  • Türleri:
  • 1:1 (Bir-tek): Her varlık örneği, diğer varlığın yalnızca bir örneğiyle ilişkilidir.
  • 1:N (Bir-çok): Bir varlık örneği, diğer varlığın birden fazla örneğiyle ilişkilidir.
  • N:M (Çok-çok): Her iki varlığın birden fazla örneği ilişkilidir.
  • Zorunlu (Mandatory): İlişki, bir varlık için zorunluysa, her örneğin ilişkide yer alması gerekir (örneğin, her Sipariş bir Müşteriye bağlı olmalı).
  • İsteğe Bağlı (Optional): İlişki zorunlu değilse, varlık örneği ilişkisiz olabilir (örneğin, bir Müşteri sipariş vermemiş olabilir).
  • Temsil:
  • Çizgilerle bağlanan varlıklar arasında kardinalite sembolleri kullanılır:
    • 1 veya | : Tek bir örnek.
    • N veya M : Birden fazla örnek.
    • 0 veya O : İsteğe bağlı (sıfır veya daha fazla).
4. Zayıf Varlıklar ve Tanımlayıcı İlişkiler
  • Zayıf varlıklar, güçlü varlıklara bağlıdır ve kendi birincil anahtarları yoktur. Tanımlayıcı ilişki (identifying relationship), zayıf varlığın kimliğini belirler.
  • Temsil: Zayıf varlıklar çift çerçeveli dikdörtgenle, tanımlayıcı ilişkiler çift çizgili eşkenar dörtgenle gösterilir.

E-Ticaret Sistemi için ER Diyagramı Örneği

Bir e-ticaret sistemi için temel varlıkları ve ilişkileri ele alalım. Bu sistemde şu varlıkları ve ilişkileri modelleyeceğiz:

  • Varlıklar: Müşteri, Sipariş, Ürün, Kategori, SiparişDetayı (zayıf varlık).
  • İlişkiler: Müşterilerin sipariş vermesi, siparişlerin ürünleri içermesi, ürünlerin kategorilere ait olması.
  • Kardinalite:
  • Bir Müşteri birden fazla Sipariş verebilir (1:N).
  • Bir Sipariş, birden fazla Ürün içerebilir ve bir Ürün birden fazla Siparişte yer alabilir (N:M).
  • Bir Ürün, yalnızca bir Kategoriye aittir (N:1).
  • SiparişDetayı, Sipariş ve Ürün arasında bir ara varlık olarak kullanılır.
ER Diyagramı Açıklaması

Aşağıda, e-ticaret sistemi için ER diyagramının metinsel bir temsili ve açıklaması yer alıyor. (Not: Grafiksel bir diyagram çizimi metin tabanlı bir ortamda sınırlıdır, bu nedenle metinsel bir temsil ve açıklamalar sunuyorum. Grafiksel diyagram için bir ER diyagram aracı, örneğin Lucidchart veya Draw.io, kullanılabilir.)

Varlıklar ve Özellikleri:

Müşteri (Güçlü Varlık)

  • Özellikler: MusteriID (PK), Ad, Soyad, Email, Telefon
  • Temsil: [Müşteri]

Sipariş (Güçlü Varlık)

  • Özellikler: SiparisID (PK), MusteriID (FK), SiparisTarihi, ToplamTutar
  • Temsil: [Sipariş]

Ürün (Güçlü Varlık)

  • Özellikler: UrunID (PK), UrunAdi, Fiyat, StokMiktari, KategoriID (FK)
  • Temsil: [Ürün]

Kategori (Güçlü Varlık)

  • Özellikler: KategoriID (PK), KategoriAdi
  • Temsil: [Kategori]

SiparişDetayı (Zayıf Varlık)

  • Özellikler: SiparisID (PK, FK), UrunID (PK, FK), Miktar, BirimFiyat
  • Temsil: [[SiparişDetayı]]

İlişkiler ve Kardinalite:

Müşteri – Sipariş (1:N):

  • Bir Müşteri, sıfır veya daha fazla Sipariş verebilir (isteğe bağlı).
  • Her Sipariş, tam olarak bir Müşteriye bağlıdır (zorunlu).
  • Temsil: [Müşteri] ----1:N----> [Sipariş]

Sipariş – SiparişDetayı (1:N, Tanımlayıcı İlişki):

  • Bir Sipariş, bir veya daha fazla SiparişDetayı içerir (zorunlu).
  • Her SiparişDetayı, tam olarak bir Siparişe bağlıdır (zayıf varlık bağı).
  • Temsil: [Sipariş] ===1:N===> [[SiparişDetayı]] (çift çizgi, tanımlayıcı ilişkiyi gösterir).

Ürün – SiparişDetayı (1:N, Tanımlayıcı İlişki):

  • Bir Ürün, sıfır veya daha fazla SiparişDetayında yer alabilir (isteğe bağlı).
  • Her SiparişDetayı, tam olarak bir Ürüne bağlıdır.
  • Temsil: [Ürün] ===1:N===> [[SiparişDetayı]]

Ürün – Kategori (N:1):

  • Bir Ürün, tam olarak bir Kategoriye aittir (zorunlu).
  • Bir Kategori, sıfır veya daha fazla Ürün içerebilir (isteğe bağlı).
  • Temsil: [Ürün] ----N:1----> [Kategori]

Metinsel ER Diyagramı Temsili:

Açıklama:

  • Müşteri ile Sipariş arasında 1:N ilişkisi, bir müşterinin birden fazla sipariş verebileceğini gösterir. Sipariş tablosunda MusteriID, yabancı anahtar olarak bulunur.
  • Sipariş ve Ürün arasında N:M ilişkisi olduğu için SiparişDetayı zayıf varlığı kullanılır. Bu, siparişin hangi ürünleri hangi miktarda içerdiğini temsil eder.
  • SiparişDetayı, hem Sipariş hem de Ürün’e bağlıdır ve her ikisinin birincil anahtarlarını içerir (SiparisID, UrunID).
  • Ürün ile Kategori arasında N:1 ilişkisi, bir ürünün yalnızca bir kategoriye ait olduğunu, ancak bir kategorinin birden fazla ürün içerebileceğini gösterir.
SQL Şemasına Dönüşüm

ER diyagramını SQL şemasına dönüştürelim:

CREATE TABLE Kategoriler (
    KategoriID INT PRIMARY KEY,
    KategoriAdi VARCHAR(50) NOT NULL
);

CREATE TABLE Urunler (
    UrunID INT PRIMARY KEY,
    UrunAdi VARCHAR(100) NOT NULL,
    Fiyat DECIMAL(10,2) NOT NULL,
    StokMiktari INT CHECK (StokMiktari >= 0),
    KategoriID INT NOT NULL,
    FOREIGN KEY (KategoriID) REFERENCES Kategoriler(KategoriID)
);

CREATE TABLE Musteriler (
    MusteriID INT PRIMARY KEY,
    Ad VARCHAR(50) NOT NULL,
    Soyad VARCHAR(50) NOT NULL,
    Email VARCHAR(100) UNIQUE,
    Telefon VARCHAR(15)
);

CREATE TABLE Siparisler (
    SiparisID INT PRIMARY KEY,
    MusteriID INT NOT NULL,
    SiparisTarihi DATE NOT NULL,
    ToplamTutar DECIMAL(10,2),
    FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID)
);

CREATE TABLE SiparisDetaylari (
    SiparisID INT,
    UrunID INT,
    Miktar INT NOT NULL CHECK (Miktar > 0),
    BirimFiyat DECIMAL(10,2) NOT NULL,
    PRIMARY KEY (SiparisID, UrunID),
    FOREIGN KEY (SiparisID) REFERENCES Siparisler(SiparisID),
    FOREIGN KEY (UrunID) REFERENCES Urunler(UrunID)
);

Açıklama:

  • Kategoriler ve Urunler arasında N:1 ilişkisi, Urunler.KategoriID yabancı anahtarıyla uygulanır.
  • Musteriler ve Siparisler arasında 1:N ilişkisi, Siparisler.MusteriID yabancı anahtarıyla temsil edilir.
  • SiparisDetaylari, N:M ilişkisini çözmek için bir ara tablodur. SiparisID ve UrunID birleşik birincil anahtar olarak kullanılır.

Kardinalite Kısıtlamalarının Önemi
  • Veri Bütünlüğü: Kardinalite, yabancı anahtarların doğru şekilde tanımlanmasını sağlar. Örneğin, bir Sipariş’in MusteriID’si NULL olamaz (zorunlu ilişki).
  • Uygulama Mantığı: Kardinalite, iş kurallarını yansıtır. Örneğin, bir Ürün’ün bir Kategori’ye zorunlu olarak bağlı olması, kategorisiz ürün olmamasını garanti eder.
  • Performans: Kardinalite, sorgu optimizasyonuna yardımcı olur. Örneğin, 1:N ilişkilerde birleştirme (join) işlemleri daha öngörülebilir olur.

Örnek Kardinalite Sorunları:

  • Eğer SiparişMüşteri ilişkisi isteğe bağlı olsaydı (0:N), müşterisiz siparişler mümkün olurdu, bu da iş mantığına aykırı olabilir.
  • N:M ilişkisi için SiparişDetayı kullanılmazsa, veri fazlalığı ve tutarsızlıklar ortaya çıkardı.

ER Diyagramının Grafiksel Temsili

Metin tabanlı bir ortamda grafiksel diyagram çizmek mümkün olmadığından, yukarıdaki metinsel temsil ve SQL kodu, diyagramın mantığını açıklar. Grafiksel bir diyagram oluşturmak için aşağıdaki adımları bir ER diyagram aracında (örneğin, Lucidchart, Draw.io) izleyebilirsiniz:

  1. Varlıkları Çizin: Müşteri, Sipariş, Ürün, Kategori için dikdörtgenler, SiparişDetayı için çift çerçeveli dikdörtgen.
  2. Özellikleri Ekleyin: Her varlığın altına özelliklerini listeleyin (örneğin, MusteriID, Ad).
  3. İlişkileri Çizin: Varlıkları bağlayan çizgilerle ilişkileri gösterin (örneğin, MüşteriSipariş için 1:N).
  4. Kardinaliteyi Belirtin: Çizgiler üzerinde 1, N, 0 gibi semboller kullanın.
  5. Tanımlayıcı İlişkileri Vurgulayın: SiparişSiparişDetayı ve ÜrünSiparişDetayı için çift çizgi kullanın.

Örnek Görselleştirme (Sözde Çizim):

UML (Unified Modeling Language) ile Veri Modelleme
UML Sınıf Diyagramlarının Veri Modellemede Kullanımı

UML sınıf diyagramları, veri modellemede şu şekilde kullanılır:

Varlıkların Tanımlanması:

  • Her sınıf, veritabanındaki bir tabloya karşılık gelir. Sınıfın özellikleri (attributes), tablonun sütunlarını temsil eder.
  • Örneğin, bir Müşteri sınıfı, Musteriler tablosunu ve MusteriID, Ad, Soyad gibi sütunları tanımlar.

İlişkilerin Modellenmesi:

  • Sınıflar arasındaki ilişkiler (örneğin, birincil/yabancı anahtar ilişkileri), UML’de çeşitli ilişki türleriyle (birleşme, genelleştirme, agregasyon, kompozisyon) modellenir.
  • Örneğin, bir Sipariş sınıfının Müşteri sınıfıyla 1:N ilişkisi, bir birleşme (association) ile gösterilir.

Kısıtlamaların Belirtilmesi:

  • UML, veri kısıtlamalarını (örneğin, NOT NULL, UNIQUE) sınıf özelliklerinde veya ilişkilerde belirtebilir.
  • Örneğin, MusteriID özelliği {unique, not null} olarak işaretlenir.

Nesne Yönelimli Tasarımın Entegrasyonu:

  • UML sınıf diyagramları, veritabanı tasarımını uygulama katmanındaki nesne yönelimli kodla (örneğin, Java, Python sınıfları) hizalar. Bu, ORM (Object-Relational Mapping) araçlarıyla (örneğin, Hibernate, SQLAlchemy) uyumluluğu artırır.

Dokümantasyon ve İletişim:

  • UML diyagramları, paydaşlar arasında teknik ve iş gereksinimlerini görselleştirir. Örneğin, bir e-ticaret sisteminin veri yapısını geliştiriciler ve iş analistleri için netleştirir.

Normalizasyon ve Optimizasyon:

  • UML diyagramları, normalizasyon sürecini destekler. Örneğin, gereksiz veri fazlalığını tespit etmek için genelleştirme/özelleştirme kullanılabilir.

UML İlişki Türleri ve Örnekler

E-ticaret sistemi örneği üzerinden genelleştirme, özelleştirme, agregasyon ve kompozisyon ilişkilerini açıklayalım. Örnek senaryo: Bir e-ticaret platformunda Müşteri, Sipariş, Ürün, KrediKarti ve Adres gibi varlıkları modelleyeceğiz.

1. Genelleştirme (Generalization)

Tanım: Bir üst sınıf (genel sınıf) ile alt sınıflar (özel sınıflar) arasındaki “is-a” (bir türdür) ilişkisidir. Üst sınıf, ortak özellikleri ve davranışları tanımlar; alt sınıflar, üst sınıfı miras alır ve kendine özgü özellikler ekler.

Veri Modellemedeki Kullanımı:

Genelleştirme, ortak özellikleri paylaşan birden fazla varlığı tek bir üst sınıfta birleştirir ve veri fazlalığını azaltır.

Veritabanında, genelleştirme genellikle üç şekilde uygulanır:

Tek Tablo (Single Table): Tüm alt sınıflar tek bir tabloda saklanır, bir ayırt edici sütun (discriminator) kullanılır.

Sınıf Başına Tablo (Table per Class): Her alt sınıf için ayrı bir tablo oluşturulur.

Birleşik Tablo (Joined Table): Üst sınıf için bir tablo, her alt sınıf için ayrı tablolar oluşturulur.

Örnek:

E-ticaret sisteminde, Kullanıcı üst sınıfı, BireyselMusteri ve KurumsalMusteri alt sınıflarını genelleştirir.

UML Temsili:

[Kullanıcı]
| KullaniciID: INT {PK}
| Ad: STRING
| Soyad: STRING
| Email: STRING {unique}
^
|\
| \
|  [BireyselMusteri]       [KurumsalMusteri]
|  | TCKimlikNo: STRING    | SirketAdi: STRING
|  | DogumTarihi: DATE     | VergiNo: STRING
  • Açıklama: Kullanıcı sınıfı ortak özellikleri (Ad, Soyad, Email) içerir. BireyselMusteri ve KurumsalMusteri, Kullanıcı’dan miras alır ve kendine özgü özellikleri ekler.

SQL Uygulaması (Tek Tablo Stratejisi):

CREATE TABLE Kullanicilar (
    KullaniciID INT PRIMARY KEY,
    Ad VARCHAR(50) NOT NULL,
    Soyad VARCHAR(50) NOT NULL,
    Email VARCHAR(100) UNIQUE,
    Tip VARCHAR(20) NOT NULL, -- Ayırt edici: 'Bireysel' veya 'Kurumsal'
    TCKimlikNo VARCHAR(11),   -- Bireysel için
    DogumTarihi DATE,         -- Bireysel için
    SirketAdi VARCHAR(100),   -- Kurumsal için
    VergiNo VARCHAR(20)       -- Kurumsal için
);

Avantajları:

Veri fazlalığını azaltır.

Ortak özelliklerin yönetimini kolaylaştırır.

Dezavantajları:

Tek tablo stratejisi, NULL değerlerin artmasına neden olabilir.

Sorgular karmaşıklaşabilir.

2. Özelleştirme (Specialization)

Tanım: Genelleştirmenin tersidir; bir üst sınıfın özelliklerini miras alan alt sınıfların özelleştirilmiş özellikler eklemesidir. Genelleştirme ve özelleştirme aynı ilişkinin iki yönünü ifade eder.

Veri Modellemedeki Kullanımı:

Özelleştirme, farklı varlık türlerinin özel ihtiyaçlarını karşılamak için kullanılır.

Veritabanında, genelleştirme ile aynı uygulama stratejileri (tek tablo, sınıf başına tablo, birleşik tablo) kullanılır.

Örnek:

Yukarıdaki genelleştirme örneğinde, BireyselMusteri ve KurumsalMusteri, Kullanıcı sınıfının özelleştirilmiş alt sınıflarıdır.

SQL Uygulaması (Birleşik Tablo Stratejisi):

CREATE TABLE Kullanicilar (
    KullaniciID INT PRIMARY KEY,
    Ad VARCHAR(50) NOT NULL,
    Soyad VARCHAR(50) NOT NULL,
    Email VARCHAR(100) UNIQUE
);

CREATE TABLE BireyselMusteriler (
    KullaniciID INT PRIMARY KEY,
    TCKimlikNo VARCHAR(11),
    DogumTarihi DATE,
    FOREIGN KEY (KullaniciID) REFERENCES Kullanicilar(KullaniciID)
);

CREATE TABLE KurumsalMusteriler (
    KullaniciID INT PRIMARY KEY,
    SirketAdi VARCHAR(100),
    VergiNo VARCHAR(20),
    FOREIGN KEY (KullaniciID) REFERENCES Kullanicilar(KullaniciID)
);

Avantajları:

Daha az NULL değer, daha temiz veri modeli.

Her alt sınıf için özel sorgular yazılabilir.

Dezavantajları:

Birleştirme (join) işlemleri gerekebilir, bu da performansı etkileyebilir.

3. Agregasyon (Aggregation)

Tanım: Bir “has-a” (sahiptir) ilişkisidir ve bir sınıfın başka bir sınıfın örneklerini içerdiğini gösterir. Agregasyon, sınıflar arasında gevşek bir bağımlılığı ifade eder; birleştirilen nesneler bağımsız olarak var olabilir.

Veri Modellemedeki Kullanımı:

Agregasyon, bir varlığın başka bir varlıkla isteğe bağlı veya geçici bir ilişki içinde olduğunu gösterir.

Veritabanında genellikle 1:N veya N:M ilişkilerle uygulanır ve yabancı anahtarlarla temsil edilir.

Örnek:

Bir Sipariş, birden fazla Ürün içerebilir, ancak Ürün’ler Sipariş’ten bağımsız olarak var olabilir (sipariş silindiğinde ürünler silinmez).

UML Temsili:

[Sipariş] ◇----1:N----> [Ürün]
| SiparisID: INT {PK}    | UrunID: INT {PK}
| SiparisTarihi: DATE    | UrunAdi: STRING
| ToplamTutar: DECIMAL   | Fiyat: DECIMAL
  • Açıklama: sembolü agregasyonu gösterir. Sipariş ve Ürün arasında N:M ilişkisi vardır, bu nedenle bir ara tablo (SiparişDetayı) kullanılır.

SQL Uygulaması:

CREATE TABLE Siparisler (
    SiparisID INT PRIMARY KEY,
    SiparisTarihi DATE NOT NULL,
    ToplamTutar DECIMAL(10,2)
);

CREATE TABLE Urunler (
    UrunID INT PRIMARY KEY,
    UrunAdi VARCHAR(100) NOT NULL,
    Fiyat DECIMAL(10,2) NOT NULL
);

CREATE TABLE SiparisDetaylari (
    SiparisID INT,
    UrunID INT,
    Miktar INT NOT NULL,
    BirimFiyat DECIMAL(10,2),
    PRIMARY KEY (SiparisID, UrunID),
    FOREIGN KEY (SiparisID) REFERENCES Siparisler(SiparisID),
    FOREIGN KEY (UrunID) REFERENCES Urunler(UrunID)
);

Avantajları:

Esnek bir ilişki modeli sağlar.

Varlıkların bağımsızlığı, veri yönetimini kolaylaştırır.

Dezavantajları:

Ara tablolar, sorgu karmaşıklığını artırabilir.

4. Kompozisyon (Composition)

Tanım: Daha güçlü bir “has-a” ilişkisidir ve bir sınıfın başka bir sınıfın parçalarını içerdiğini gösterir. Kompozisyonda, bütün (whole) olmadan parçalar (parts) var olamaz; yani, bütün silindiğinde parçalar da silinir.

Veri Modellemedeki Kullanımı:

Kompozisyon, bir varlığın yaşam döngüsünün başka bir varlığa sıkı sıkıya bağlı olduğu durumlarda kullanılır.

Veritabanında genellikle 1:N ilişkilerle uygulanır ve ON DELETE CASCADE gibi kısıtlamalarla desteklenir.

Örnek:

Bir Müşteri, birden fazla Adres’e sahip olabilir, ancak bu adresler yalnızca o müşteriye aittir. Müşteri silindiğinde, adresler de silinmelidir.

UML Temsili:

  • Açıklama: sembolü kompozisyonu gösterir. Adres, Müşteri olmadan var olamaz.

SQL Uygulaması: CREATE TABLE Musteriler ( MusteriID INT PRIMARY KEY, Ad VARCHAR(50) NOT NULL, Soyad VARCHAR(50) NOT NULL, Email VARCHAR(100) UNIQUE ); CREATE TABLE Adresler ( AdresID INT PRIMARY KEY, MusteriID INT NOT NULL, Sehir VARCHAR(50), PostaKodu VARCHAR(10), FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID) ON DELETE CASCADE );

Avantajları:

Veri bütünlüğünü korur (örneğin, yetim adreslerin oluşmasını engeller).

Yaşam döngüsü bağımlılığı açıkça tanımlanır.

Dezavantajları:

Sıkı bağımlılık, esnekliği azaltabilir.


E-Ticaret Sistemi için UML Sınıf Diyagramı Örneği

Aşağıda, e-ticaret sistemi için bir UML sınıf diyagramının metinsel temsili ve açıklaması yer alıyor. (Grafiksel bir diyagram için Lucidchart, Draw.io gibi araçlar kullanılabilir.)

Sınıflar ve İlişkiler:

[Kullanıcı]
| KullaniciID: INT {PK}
| Ad: STRING
| Soyad: STRING
| Email: STRING {unique}
^
|\
| \
|  [BireyselMusteri] ◇----1:N----> [Sipariş] ◇----N:M----> [Ürün]
|  | TCKimlikNo: STRING   | SiparisID: INT {PK}   | UrunID: INT {PK}
|  | DogumTarihi: DATE    | SiparisTarihi: DATE   | UrunAdi: STRING
|                         | ToplamTutar: DECIMAL  | Fiyat: DECIMAL
|  [KurumsalMusteri] ◆----1:N----> [Adres]
|  | SirketAdi: STRING    | AdresID: INT {PK}
|  | VergiNo: STRING      | MusteriID: INT {FK}
|                         | Sehir: STRING
|                         | PostaKodu: STRING

Açıklama:

Genelleştirme/Özelleştirme:

  • Kullanıcı üst sınıfı, BireyselMusteri ve KurumsalMusteri alt sınıflarını genelleştirir. Ortak özellikler (Ad, Soyad, Email) Kullanıcı’da tanımlanır.

Agregasyon:

  • Sipariş ile Ürün arasında N:M agregasyon ilişkisi vardır. Bu, SiparişDetayı ara tablosuyla uygulanır (diyagramda gösterilmemiştir, ancak SQL’de tanımlanır).
  • BireyselMusteri ile Sipariş arasında 1:N agregasyon ilişkisi vardır; siparişler müşteriden bağımsız olarak var olabilir.

Kompozisyon:

  • KurumsalMusteri ile Adres arasında 1:N kompozisyon ilişkisi vardır. Adresler, yalnızca ilgili müşteriye aittir ve müşteri silindiğinde adresler de silinir.

Kısıtlamalar:

  • KullaniciID, SiparisID, UrunID, AdresID birincil anahtar olarak işaretlenir ({PK}).
  • Email benzersizdir ({unique}).

SQL Şeması:

CREATE TABLE Kullanicilar (
    KullaniciID INT PRIMARY KEY,
    Ad VARCHAR(50) NOT NULL,
    Soyad VARCHAR(50) NOT NULL,
    Email VARCHAR(100) UNIQUE,
    Tip VARCHAR(20) NOT NULL -- 'Bireysel' veya 'Kurumsal'
);

CREATE TABLE BireyselMusteriler (
    KullaniciID INT PRIMARY KEY,
    TCKimlikNo VARCHAR(11),
    DogumTarihi DATE,
    FOREIGN KEY (KullaniciID) REFERENCES Kullanicilar(KullaniciID)
);

CREATE TABLE KurumsalMusteriler (
    KullaniciID INT PRIMARY KEY,
    SirketAdi VARCHAR(100),
    VergiNo VARCHAR(20),
    FOREIGN KEY (KullaniciID) REFERENCES Kullanicilar(KullaniciID)
);

CREATE TABLE Adresler (
    AdresID INT PRIMARY KEY,
    MusteriID INT NOT NULL,
    Sehir VARCHAR(50),
    PostaKodu VARCHAR(10),
    FOREIGN KEY (MusteriID) REFERENCES KurumsalMusteriler(KullaniciID) ON DELETE CASCADE
);

CREATE TABLE Siparisler (
    SiparisID INT PRIMARY KEY,
    MusteriID INT NOT NULL,
    SiparisTarihi DATE NOT NULL,
    ToplamTutar DECIMAL(10,2),
    FOREIGN KEY (MusteriID) REFERENCES BireyselMusteriler(KullaniciID)
);

CREATE TABLE Urunler (
    UrunID INT PRIMARY KEY,
    UrunAdi VARCHAR(100) NOT NULL,
    Fiyat DECIMAL(10,2) NOT NULL
);

CREATE TABLE SiparisDetaylari (
    SiparisID INT,
    UrunID INT,
    Miktar INT NOT NULL,
    BirimFiyat DECIMAL(10,2),
    PRIMARY KEY (SiparisID, UrunID),
    FOREIGN KEY (SiparisID) REFERENCES Siparisler(SiparisID),
    FOREIGN KEY (UrunID) REFERENCES Urunler(UrunID)
);

UML Sınıf Diyagramlarının Veri Modellemedeki Avantajları
  • Soyutlama: İş mantığını teknik detaylardan ayırır.
  • Esneklik: Nesne yönelimli tasarım ile veritabanı tasarımı arasında köprü kurar.
  • İletişim: Paydaşlar arasında net bir görsel iletişim sağlar.
  • Normalizasyon Desteği: Genelleştirme ve özelleştirme, veri fazlalığını azaltır.
  • Hata Önleme: İlişkilerin (agregasyon, kompozisyon) açıkça tanımlanması, tasarım hatalarını azaltır.
Domain Driven Design ve Veri Modelleme
DDD Prensiplerinin Veri Modellemede Uygulanması

DDD, veri modellemede iş mantığını ve iş alanını (domain) ön planda tutar. Temel prensipler ve bunların veri modellemedeki uygulamaları şunlardır:

Ubiquitous Language (Ortak Dil):

  • İş uzmanları, geliştiriciler ve diğer paydaşlar arasında ortak bir dil kullanılır. Bu dil, hem kodda hem de veritabanı tasarımında tutarlı bir şekilde yansıtılır.
  • Veri Modellemedeki Uygulama: Tablo ve sütun isimleri, iş terimlerini yansıtır (örneğin, Order yerine Sipariş, Customer yerine Müşteri).

Bounded Context:

  • İş alanını daha küçük, bağımsız bağlamlara böler. Her bağlam, kendi modelini ve dilini tanımlar, böylece karmaşıklık azalır.
  • Veri Modellemedeki Uygulama: Her bağlam için ayrı bir şema veya veritabanı kullanılır, böylece farklı bağlamlar arasında çakışmalar önlenir.

Varlık (Entity):

  • Benzersiz bir kimliğe sahip olan ve yaşam döngüsü boyunca izlenen nesnelerdir.
  • Veri Modellemedeki Uygulama: Varlıklar, veritabanında birincil anahtar (primary key) ile tanımlı tablolar olarak modellenir.

Değer Nesnesi (Value Object):

  • Kimlikten ziyade özellikleriyle tanımlanan, değişmez (immutable) nesnelerdir.
  • Veri Modellemedeki Uygulama: Değer nesneleri, ayrı tablolar yerine genellikle bir varlığın sütunları veya gömülü yapılar olarak saklanır.

Toplu Kök (Aggregate Root):

  • Bir grup varlığı ve değer nesnesini bir arada yöneten, veri bütünlüğünü sağlayan bir varlıktır. Dış dünya, yalnızca toplu kök üzerinden bu gruba erişir.
  • Veri Modellemedeki Uygulama: Toplu kök, bir tablo olarak modellenir ve ilgili varlık/değer nesneleriyle ilişkiler (yabancı anahtarlar) aracılığıyla bağlanır.

Repository:

  • Veritabanı ile uygulama arasındaki veri erişimini soyutlar. Toplu kökleri saklamak ve almak için kullanılır.
  • Veri Modellemedeki Uygulama: Repository, SQL sorgularını veya ORM (Object-Relational Mapping) işlemlerini kapsar.

Domain Events:

  • İş mantığında önemli olayları temsil eder (örneğin, bir siparişin tamamlanması).
  • Veri Modellemedeki Uygulama: Olaylar, bir olay günlüğü tablosunda saklanabilir veya mesaj kuyruklarına (örneğin, Kafka) gönderilebilir.

E-Ticaret Sistemi Örneği Üzerinden DDD Kavramları

Bir e-ticaret platformunda, sipariş yönetimi ve müşteri yönetimi işlevlerini modelleyelim. Bu örnekte, DDD prensiplerini veri modellemede nasıl uygulayacağımızı göstereceğim.

1. Bounded Context

Tanım: İş alanını bağımsız bağlamlara böler. Her bağlam, kendi modelini ve dilini tanımlar, böylece farklı bağlamlar arasında anlam karışıklığı önlenir.

E-Ticaret Örneği:

  • Sipariş Yönetimi Bağlamı: Sipariş oluşturma, ürün ekleme, ödeme işlemleri gibi işlevleri kapsar.
  • Müşteri Yönetimi Bağlamı: Müşteri profilleri, adresler ve iletişim bilgileri gibi işlevleri kapsar.
  • Her bağlam için ayrı bir veritabanı şeması veya modül oluşturulabilir, ancak bağlamlar arasında entegrasyon gerekebilir (örneğin, bir siparişin müşteri bilgilerine ihtiyacı vardır).

Veri Modellemedeki Uygulama:

  • Sipariş Yönetimi Şeması (orders): Sipariş, SiparişKalemi, Ödeme gibi tablolar içerir.
  • Müşteri Yönetimi Şeması (crm): Müşteri, Adres gibi tablolar içerir.
  • SQL Örneği:
  CREATE SCHEMA orders;
  CREATE SCHEMA crm;

Neden Önemli?:

  • Sipariş Yönetiminde Müşteri, yalnızca MusteriID ve temel bilgilerle ilgilenirken, Müşteri Yönetiminde detaylı profil bilgileri (örneğin, DogumTarihi) yer alır. Bu ayrım, her bağlamın kendi modelini optimize etmesini sağlar.

2. Varlık (Entity)

Tanım: Benzersiz bir kimliğe sahip, yaşam döngüsü boyunca izlenen nesnelerdir. Varlıkların kimlikleri, onları diğer nesnelerden ayırır.

E-Ticaret Örneği:

  • Müşteri: Her müşteri, benzersiz bir MusteriID ile tanımlanır. Müşterinin adı veya adresi değişebilir, ancak kimliği sabittir.
  • Sipariş: Her sipariş, benzersiz bir SiparisID ile tanımlanır. Siparişin durumu (örneğin, “Onaylandı”, “Kargoda”) değişebilir.

Veri Modellemedeki Uygulama:

  • Varlıklar, birincil anahtarlarla tanımlı tablolar olarak modellenir.
  • SQL Örneği:
  CREATE TABLE crm.Musteriler (
      MusteriID INT PRIMARY KEY,
      Ad VARCHAR(50) NOT NULL,
      Soyad VARCHAR(50) NOT NULL,
      Email VARCHAR(100) UNIQUE
  );

  CREATE TABLE orders.Siparisler (
      SiparisID INT PRIMARY KEY,
      MusteriID INT NOT NULL,
      SiparisTarihi DATE NOT NULL,
      Durum VARCHAR(20) NOT NULL,
      FOREIGN KEY (MusteriID) REFERENCES crm.Musteriler(MusteriID)
  );

Neden Önemli?:

  • MusteriID ve SiparisID, varlıkların benzersizliğini sağlar ve yaşam döngüsü boyunca (örneğin, sipariş durumu değiştiğinde) izlenebilirliği korur.

3. Değer Nesnesi (Value Object)

Tanım: Kimlikten ziyade özellikleriyle tanımlanan, değişmez nesnelerdir. Değer nesneleri, genellikle bir varlığın parçasıdır ve kendi başlarına bir yaşam döngüsüne sahip değildir.

E-Ticaret Örneği:

  • Adres: Bir müşterinin adresi (örneğin, Sehir, PostaKodu), benzersiz bir kimliğe sahip değildir; yalnızca özellikleriyle tanımlanır.
  • Para: Bir siparişin toplam tutarı (örneğin, 100.50 USD), miktar ve para birimiyle tanımlanır.

Veri Modellemedeki Uygulama:

  • Değer nesneleri, genellikle bir varlığın tablosunda sütunlar olarak veya gömülü yapılar olarak saklanır. Büyük veya tekrarlanan değer nesneleri için ayrı tablolar kullanılabilir.
  • SQL Örneği (Adres için):
  CREATE TABLE crm.Adresler (
      AdresID INT PRIMARY KEY,
      MusteriID INT NOT NULL,
      Sehir VARCHAR(50),
      PostaKodu VARCHAR(10),
      Ulke VARCHAR(50),
      FOREIGN KEY (MusteriID) REFERENCES crm.Musteriler(MusteriID) ON DELETE CASCADE
  );
  • Alternatif olarak, adres bilgileri Musteriler tablosuna gömülebilir:
ALTER TABLE crm.Musteriler
ADD Sehir VARCHAR(50),
ADD PostaKodu VARCHAR(10),
ADD Ulke VARCHAR(50);
  • SQL Örneği (Para için):
ALTER TABLE orders.Siparisler
ADD ToplamTutar DECIMAL(10,2),
ADD ParaBirimi VARCHAR(3) DEFAULT 'USD';

Neden Önemli?:

  • Değer nesneleri, iş mantığını sadeleştirir ve veri tutarlılığını sağlar. Örneğin, Adres değişmez bir yapı olarak modellenirse, her değişiklik yeni bir adres nesnesi oluşturur, bu da geçmiş verilerin korunmasını sağlar.

4. Toplu Kök (Aggregate Root)

Tanım: Bir toplu (aggregate), bir grup varlığı ve değer nesnesini bir arada tutan ve veri bütünlüğünü sağlayan bir varlıktır. Dış dünya, yalnızca toplu kök üzerinden bu gruba erişir.

E-Ticaret Örneği:

  • Sipariş Toplusu:
  • Toplu Kök: Sipariş
  • İçerdiği Nesneler:
    • Varlık: SiparişKalemi (bir siparişin içerdiği ürünler)
    • Değer Nesnesi: Para (sipariş toplamı), Adres (teslimat adresi)
  • İş Kuralı: Bir siparişin durumu, yalnızca Sipariş üzerinden değiştirilebilir (örneğin, “Kargoda” durumuna geçerken tüm kalemler kontrol edilir).

Veri Modellemedeki Uygulama:

  • Toplu kök, bir tablo olarak modellenir ve ilgili nesneler, yabancı anahtarlarla bağlanır. Toplu kök, veri erişiminde sınırları belirler.
  • SQL Örneği:
  CREATE TABLE orders.Siparisler (
      SiparisID INT PRIMARY KEY,
      MusteriID INT NOT NULL,
      SiparisTarihi DATE NOT NULL,
      Durum VARCHAR(20) NOT NULL,
      ToplamTutar DECIMAL(10,2),
      ParaBirimi VARCHAR(3) DEFAULT 'USD',
      TeslimatSehir VARCHAR(50), -- Değer nesnesi: Teslimat Adresi
      TeslimatPostaKodu VARCHAR(10),
      TeslimatUlke VARCHAR(50),
      FOREIGN KEY (MusteriID) REFERENCES crm.Musteriler(MusteriID)
  );

  CREATE TABLE orders.SiparisKalemleri (
      SiparisKalemiID INT PRIMARY KEY,
      SiparisID INT NOT NULL,
      UrunID INT NOT NULL,
      Miktar INT NOT NULL CHECK (Miktar > 0),
      BirimFiyat DECIMAL(10,2) NOT NULL,
      FOREIGN KEY (SiparisID) REFERENCES orders.Siparisler(SiparisID) ON DELETE CASCADE,
      FOREIGN KEY (UrunID) REFERENCES orders.Urunler(UrunID)
  );

  CREATE TABLE orders.Urunler (
      UrunID INT PRIMARY KEY,
      UrunAdi VARCHAR(100) NOT NULL,
      Fiyat DECIMAL(10,2) NOT NULL
  );
  • Açıklama:
  • Sipariş, toplu köktür ve SiparisID ile tanımlanır.
  • SiparişKalemleri, Sipariş’e bağlı bir varlıktır ve ON DELETE CASCADE ile sipariş silindiğinde kalemler de silinir.
  • TeslimatSehir, TeslimatPostaKodu, TeslimatUlke ve ToplamTutar, ParaBirimi değer nesneleridir ve Sipariş tablosuna gömülüdür.
  • Dış dünya (örneğin, uygulama), SiparişKalemleri’ne doğrudan erişemez; yalnızca Sipariş üzerinden erişilir.

Neden Önemli?:

  • Toplu kök, veri bütünlüğünü korur. Örneğin, bir siparişin toplam tutarı, kalemlerin birim fiyatları ve miktarlarıyla tutarlı olmalıdır. Bu kontrol, Sipariş toplu kökü tarafından yapılır.

E-Ticaret Sistemi için UML Sınıf Diyagramı ile DDD Modeli

Aşağıda, e-ticaret sisteminin DDD tabanlı bir UML sınıf diyagramının metinsel temsili yer alıyor. (Grafiksel diyagram için Lucidchart veya Draw.io kullanılabilir.)

UML Temsili:

Bounded Context: Sipariş Yönetimi
  [Sipariş] (Aggregate Root)
  | SiparisID: INT {PK}
  | MusteriID: INT {FK}
  | SiparisTarihi: DATE
  | Durum: STRING
  | ToplamTutar: DECIMAL
  | ParaBirimi: STRING
  | TeslimatAdresi: Adres
  | + degistirDurum(yeniDurum: STRING)
  ◆----1:N----> [SiparişKalemi]
  | SiparisKalemiID: INT {PK}
  | SiparisID: INT {FK}
  | UrunID: INT {FK}
  | Miktar: INT
  | BirimFiyat: DECIMAL
  ◇----N:1----> [Ürün]
  | UrunID: INT {PK}
  | UrunAdi: STRING
  | Fiyat: DECIMAL

Bounded Context: Müşteri Yönetimi
  [Müşteri] (Aggregate Root)
  | MusteriID: INT {PK}
  | Ad: STRING
  | Soyad: STRING
  | Email: STRING {unique}
  | + guncelleEmail(yeniEmail: STRING)
  ◆----1:N----> [Adres] (Value Object)
  | Sehir: STRING
  | PostaKodu: STRING
  | Ulke: STRING

Açıklama:

  • Bounded Context:
  • Sipariş Yönetimi: Sipariş, SiparişKalemi, Ürün ve ilgili iş mantığını içerir.
  • Müşteri Yönetimi: Müşteri ve Adres’i içerir.
  • Varlık:
  • Sipariş, SiparişKalemi, Ürün ve Müşteri, benzersiz kimlikleriyle varlıklardır.
  • Değer Nesnesi:
  • Adres, kimlikten ziyade özellikleriyle (Sehir, PostaKodu, Ulke) tanımlanır.
  • Sipariş içindeki TeslimatAdresi ve ToplamTutar/ParaBirimi de değer nesneleridir.
  • Toplu Kök:
  • Sipariş, SiparişKalemleri ve TeslimatAdresi’ni kapsayan bir toplu köktür. Uygulama, kalemlere doğrudan erişemez; Sipariş üzerinden erişir.
  • Müşteri, Adres’leri kapsayan bir toplu köktür.

DDD’nin Veri Modellemedeki Avantajları

İş Mantığı Odaklı Tasarım:

  • Veritabanı, iş kurallarını (örneğin, sipariş durumu geçişleri) doğru bir şekilde yansıtır.

Esneklik ve Sürdürülebilirlik:

  • Bounded Context’ler, farklı iş alanlarını izole ederek değişiklikleri kolaylaştırır.

Veri Bütünlüğü:

  • Toplu kökler, ilgili nesneler arasında tutarlılığı sağlar.

Kod-Veritabanı Uyumu:

  • Varlık ve değer nesneleri, uygulama kodundaki sınıflarla hizalanır (örneğin, ORM ile).

Karmaşıklığın Azaltılması:

  • Bounded Context’ler, büyük sistemleri yönetilebilir parçalara böler.
Kaynakça:

Bir şeyi başarmak ne kadar zorsa, zaferin tadı o kadar güzeldir.

Pele

Bir sonraki yazıda görüşmek dileğiyle!”

Leave a Reply

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir