Ürün kataloğunda her kategorinin farklı özellik seti vardır: elektronikte voltaj ve garanti süresi, giyimde beden ve kumaş tipi. Klasik normalizasyonla her özellik için EAV (Entity-Attribute-Value) tablosu kurmak sorguları karmaşıklaştırır. Alternatif: JSON kolon ile esnek şema. PostgreSQL jsonb, SQL Server NVARCHAR(JSON), MySQL JSON tipi bu ihtiyaca yanıt verir. Ancak JSON her sorunun cevabı değildir; yanlış kullanımda indeks kullanılamayan full table scan ve veri bütünlüğü kaybı yaşanır.
JSON kolon ne zaman mantıklı?
- Şema nadiren sorgulanan, sık değişen metadata (UI config, entegrasyon payload)
- Dış sistemden gelen yarı yapılandırılmış veri (webhook body arşivi)
- Prototip aşamasında henüz stabilize olmamış alan seti
- Okuma ağırlıklı, key bazlı filtre nadiren gereken veri
Ne zaman kaçınılmalı: sık join gereken ilişkisel veri, raporlama ve aggregate ağırlıklı alanlar, sıkı referential integrity gereksinimi, yüksek kartinaliteli filtre (milyonlarca satırda JSON path arama).
PostgreSQL jsonb
jsonb binary formatta saklanır; parse maliyeti yazmada, okuma ve indekslemede avantaj sağlar. Operatörler:
SELECT * FROM products
WHERE attributes @> '{"color": "red"}';
SELECT attributes->>'voltage' AS voltage
FROM products WHERE category_id = 5;
GIN indeks
JSON path sorgularını hızlandırmak için GIN indeks:
CREATE INDEX idx_products_attrs ON products USING GIN (attributes);
Belirli key için expression index daha seçici olabilir:
CREATE INDEX idx_products_voltage ON products
((attributes->>'voltage')) WHERE category_id = 1;
SQL Server JSON
SQL Server JSON'u native tip olarak değil, NVARCHAR içinde tutar. OPENJSON, JSON_VALUE, JSON_QUERY fonksiyonları sorgu ve computed column ile kullanılır:
SELECT JSON_VALUE(Attributes, '$.color') AS color
FROM Products
WHERE JSON_VALUE(Attributes, '$.brand') = 'Acme';
Persisted computed column + indeks sık sorgulanan JSON alanları için uygundur.
EF Core ile JSON mapping
EF Core 7+ owned entity JSON kolona map edilebilir:
modelBuilder.Entity()
.OwnsOne(p => p.Attributes, b =>
{
b.ToJson();
});
Owned type içindeki property değişiklikleri JSON kolona serialize edilir. Sorgu tarafında JSON path desteği provider'a bağlıdır; PostgreSQL'de daha olgun, SQL Server'da sınırlı.
Hibrit model: sabit + JSON
Pratik tasarım: sık sorgulanan alanlar normal kolon, nadir/esnek alanlar JSON:
CREATE TABLE products (
id BIGSERIAL PRIMARY KEY,
sku VARCHAR(32) NOT NULL,
name TEXT NOT NULL,
price NUMERIC(12,2) NOT NULL,
category_id INT NOT NULL REFERENCES categories(id),
extra_attributes JSONB NOT NULL DEFAULT '{}'
);
Raporlama price ve category_id üzerinden; detay sayfası extra_attributes parse eder. Zamanla sık kullanılan JSON key'leri promote edilip gerçek kolona taşınabilir (migration ile).
Veri bütünlüğü ve validasyon
JSON kolon CHECK constraint ile sınırlandırılabilir:
ALTER TABLE products ADD CONSTRAINT chk_attrs_object
CHECK (jsonb_typeof(extra_attributes) = 'object');
Uygulama katmanında JSON Schema validasyonu yazma öncesi zorunlu kılınmalıdır. Veritabanı trigger ile schema doğrulama mümkün ancak bakım maliyeti yüksektir.
Migration: JSON'dan kolona
JSON aşırı kullanıldığında performans düşer; promote migration planlanır:
- Yeni kolon ekle (nullable)
- Backfill: UPDATE ... SET col = attributes->>'key'
- Uygulama dual-write (JSON + kolon)
- Sorguları kolona taşı
- JSON key'ini kaldır veya deprecated bırak
JSON vs EAV
EAV (Entity-Attribute-Value) üç kolonlu generic tablo: EntityId, Key, Value. Esneklik yüksek, join cehennemi garantili. JSON tek kolonda okunabilir snapshot sunar; pivot gerektirmez. Raporlama EAV'den daha kolay değilse bile uygulama kodu basittir. Çok boyutlu analitik gerekiyorsa JSON'dan ETL ile data warehouse'a aktarım tercih edilir.
Performans tuzakları
- JSON içinde büyük blob (base64 resim) saklamak
- GIN indeks olmadan @> sorgusu full scan
- Her satırda farklı key seti — expression index planlanamaz
- UPDATE ile tüm JSON dokümanını yeniden yazmak (partial update yok)
Özet
JSON kolonlar esnek şema ihtiyacında güçlü araçtır; ilişkisel disiplinin yerini tamamen almamalıdır. Hibrit model, GIN/expression indeks, uygulama validasyonu ve promote migration stratejisi ile denge kurulur. Karar kriteri: alan ne sıklıkla sorgulanıyor, join gerekiyor mu, şema ne kadar stabil — cevaplar JSON kullanımını belirler.
Operasyonel perspektif
JSON kolonlar ne zaman? konusunda üretim ortamında karşılaşılan senaryolar, geliştirme ortamından farklıdır. Trafik hacmi, eşzamanlı bağlantı sayısı, disk I/O ve replikasyon gecikmesi gibi faktörler tasarım kararlarını doğrudan etkiler. Metrik toplama ve düzenli kapasite gözden geçirmesi, sorunları kullanıcı şikâyetine dönüşmeden yakalamayı sağlar.
Kapasite planlama
Veritabanı katmanında CPU, bellek, disk throughput ve connection pool kullanımı birlikte izlenmelidir. Ani trafik artışlarında autoscaling uygulama katmanında mümkün olsa da veritabanı ölçeklendirmesi genellikle planlı yapılır. Read replica eklemek, connection pool boyutunu artırmak veya sorgu optimizasyonu yapmak gibi seçenekler yük testi sonuçlarına göre sıralanmalıdır.
Güvenlik ve erişim kontrolü
Veritabanı kullanıcıları en az ayrıcalık ilkesine göre tanımlanmalıdır. Uygulama hesabı yalnızca gerekli DML yetkilerine sahip olmalı; DDL ve yönetim işlemleri ayrı role ayrılmalıdır. Bağlantı string'leri secret manager'da tutulmalı, rotation politikası uygulanmalıdır. Audit log erişimi yalnızca denetim ve operasyon rollerine açık olmalıdır.
Ekip disiplini ve dokümantasyon
Mimari kararlar Architecture Decision Record (ADR) ile belgelenmelidir. Onboarding dokümanında bu konuya özel bölüm yer almalı; yeni geliştiriciler global filter, routing kuralı veya yedekleme penceresi gibi kritik detayları atlamamalıdır. Code review checklist'ine ilgili maddeler eklenmesi regresyon riskini azaltır.
Kalite kapıları
- Pull request'te ilgili entegrasyon testlerinin çalışması
- Staging ortamında gerçekçi veri hacmi ile smoke test
- Performans regression eşiği (p95 latency, sorgu sayısı)
- Migration rollback planının PR açıklamasında belirtilmesi
Bu disiplinler tek başına mucize yaratmaz; ancak veritabanı katmanındaki hataların maliyeti yüksek olduğundan, erken yakalama yatırımı uzun vadede ödenir. Post-incident review'larda kök neden analizi veritabanı tasarımına geri beslenmelidir.
Operasyonel perspektif
JSON kolonlar ne zaman? konusunda üretim ortamında karşılaşılan senaryolar, geliştirme ortamından farklıdır. Trafik hacmi, eşzamanlı bağlantı sayısı, disk I/O ve replikasyon gecikmesi gibi faktörler tasarım kararlarını doğrudan etkiler. Metrik toplama ve düzenli kapasite gözden geçirmesi, sorunları kullanıcı şikâyetine dönüşmeden yakalamayı sağlar.
Kapasite planlama
Veritabanı katmanında CPU, bellek, disk throughput ve connection pool kullanımı birlikte izlenmelidir. Ani trafik artışlarında autoscaling uygulama katmanında mümkün olsa da veritabanı ölçeklendirmesi genellikle planlı yapılır. Read replica eklemek, connection pool boyutunu artırmak veya sorgu optimizasyonu yapmak gibi seçenekler yük testi sonuçlarına göre sıralanmalıdır.
Güvenlik ve erişim kontrolü
Veritabanı kullanıcıları en az ayrıcalık ilkesine göre tanımlanmalıdır. Uygulama hesabı yalnızca gerekli DML yetkilerine sahip olmalı; DDL ve yönetim işlemleri ayrı role ayrılmalıdır. Bağlantı string'leri secret manager'da tutulmalı, rotation politikası uygulanmalıdır. Audit log erişimi yalnızca denetim ve operasyon rollerine açık olmalıdır.
Ekip disiplini ve dokümantasyon
Mimari kararlar Architecture Decision Record (ADR) ile belgelenmelidir. Onboarding dokümanında bu konuya özel bölüm yer almalı; yeni geliştiriciler global filter, routing kuralı veya yedekleme penceresi gibi kritik detayları atlamamalıdır. Code review checklist'ine ilgili maddeler eklenmesi regresyon riskini azaltır.
Kalite kapıları
- Pull request'te ilgili entegrasyon testlerinin çalışması
- Staging ortamında gerçekçi veri hacmi ile smoke test
- Performans regression eşiği (p95 latency, sorgu sayısı)
- Migration rollback planının PR açıklamasında belirtilmesi
Bu disiplinler tek başına mucize yaratmaz; ancak veritabanı katmanındaki hataların maliyeti yüksek olduğundan, erken yakalama yatırımı uzun vadede ödenir. Post-incident review'larda kök neden analizi veritabanı tasarımına geri beslenmelidir.