
Veritabanında JSON Alanlar: Ne Zaman Kullanılır, Ne Zaman Zarar Verir?
Her yeni özellik için tabloya sütun eklemekten sıkıldınız ve tüm ek bilgileri tek bir JSON alanına koymaya başladınız. Esneklik harika — ta ki o alandaki bir değere göre filtreleme yapmanız gerekene kadar.
Bu yazı, veritabanında yapılandırılmamış alan kullanımını ele alıyor.
Uygun Kullanım Alanları
| Veri türü | Uygunluk |
|---|---|
| Dış servis yanıtı | Çok uygun |
| Kullanıcı tercihleri | Uygun |
| Denetim kaydı ayrıntısı | Uygun |
| Ürün fiyatı | Kesinlikle uygun değil |
| Sipariş durumu | Uygun değil |
Birinci satır en doğru kullanımdır: bir ödeme sağlayıcısının döndürdüğü tam yanıtı olduğu gibi saklamak, ileride bir uyuşmazlıkta ne alındığını kanıtlar ve o yapının değişmesi sizi etkilemez.
Bu veri sorgulanmaz, yalnızca saklanır ve gerektiğinde okunur.
Dördüncü ve beşinci satırlar ise sürekli filtrelenen ve sıralanan verilerdir; sonraki bölümde nedeni açıklanıyor.
Sorgulama Maliyeti
- Normal sütun doğrudan dizinlenir.
- JSON içi değer çıkarılmalıdır.
- Çıkarma her satırda yapılır.
Üçüncü madde performans farkını yaratır: bir JSON alanının içindeki değere göre filtreleme yapmak, veritabanının her satırda o yapıyı ayrıştırıp değeri çıkarması demektir — milyonlarca satırlı bir tabloda bu işlem sorguyu kabul edilemez biçimde yavaşlatır.
Normal bir sütunda ise dizin doğrudan kullanılır ve arama anında biter.
Modern veritabanları JSON içi değerler için de dizin oluşturmaya izin verir ama bu ek yapılandırma gerektirir.
Ve o dizin yalnızca dizinlediğiniz belirli yol için çalışır.
JSON İçinde Dizin
- Belirli bir yol için üretilmiş sütun tanımlayın.
- O sütunu dizinleyin.
- Sorgular dizini kullanır.
Bu yöntem çalışır ama bir çelişki üretir: bir JSON alanının içindeki değeri dizinlemek için onu ayrı bir sütuna çıkarmanız gerekir — o hâlde en baştan normal bir sütun kullanmak daha basit olurdu.
Bu, JSON kullanımının sınırını gösteren pratik bir testtir.
Sorgulayacağınız her alan için sonunda bir sütun oluşturacaksanız, JSON size esneklik değil karmaşıklık kazandırıyor demektir.
Bu nedenle sorgulanan veriler baştan sütun olmalıdır.
Doğrulama Kaybı
| Normal sütun | JSON alanı |
|---|---|
| Tür zorlanır | Her tür kabul edilir |
| Boş bırakılamaz kısıtı | Alan hiç olmayabilir |
| Yabancı anahtar | İlişki kurulamaz |
| Benzersizlik | Zorlanamaz |
İkinci satır zamanla ciddi bir soruna dönüşür: JSON alanında bir anahtarın varlığı garanti edilemez — kodunuz o anahtarın hep bulunacağını varsayarsa, eski kayıtlarda o alan olmadığı için beklenmedik hatalar verir.
Bu, zamanla eklenen alanlarda kaçınılmazdır.
Her okuma varsayılan değer düşünmek zorunda kalır ve kod karmaşıklaşır.
Dördüncü satır ise iş kurallarını uygulama katmanına taşır ve yarış koşullarına açık hâle getirir.
Kısmi Güncelleme
- Tüm alanı okuyup yazmak risklidir.
- Eşzamanlı güncelleme kaybolur.
- Veritabanı fonksiyonları daha güvenlidir.
İkinci madde sessiz veri kaybı üretir: iki işlem aynı JSON alanının farklı anahtarlarını güncelliyorsa ve her ikisi de tüm alanı okuyup geri yazıyorsa, ikinci yazma birincinin değişikliğini siler — normal sütunlarda bu sorun hiç yaşanmaz.
Bu kayıp hata vermez ve fark edilmesi çok zordur.
Üçüncü madde çözümü verir. Veritabanının JSON güncelleme fonksiyonları yalnızca ilgili anahtarı değiştirir.
Bu, tüm alanı okuyup yazma ihtiyacını ortadan kaldırır.
Boyut ve Performans
- JSON alanı büyüyebilir.
- Satır boyutu artar.
- Okuma maliyeti yükselir.
Üçüncü madde beklenmedik bir yavaşlama üretir: tabloda büyük bir JSON alanı varsa, o alanı hiç kullanmayan sorgular bile daha fazla veri okumak zorunda kalır — satır büyüdükçe her sorgu yavaşlar.
Bu, listeleme sayfalarında belirgin hâle gelir.
Çözüm, büyük JSON verisini ayrı bir tabloya taşımaktır.
Ana tablo hafif kalır, ayrıntı yalnızca gerektiğinde okunur.
Şemasızlığın Bedeli
| Beklenti | Gerçek |
|---|---|
| Şema yok, göç yok | Göç koda taşınır |
| İstediğim alanı eklerim | Eski kayıtlar farklı kalır |
| Esneklik kazandım | Belirsizlik kazandım |
Birinci satır en yaygın yanılgıdır: şema değişikliği ortadan kalkmaz, yalnızca veritabanından koda taşınır — artık her okuma noktasında alanın var olup olmadığını kontrol etmek zorundasınız ve bu kontrol unutulduğunda hata çıkar.
Veritabanı göçü açık ve tek yerdedir; kod içi kontroller ise dağınıktır.
Üçüncü satır ise uzun vadeli sonucu özetler. Bir alanın hangi kayıtlarda hangi biçimde olduğu zamanla bilinmez hâle gelir.
Bu belirsizlik, yeni ekip üyeleri için ciddi bir engeldir.
Karar Testi
- Bu alana göre filtreleyecek miyim?
- Sıralayacak mıyım?
- Başka tabloyla ilişkilendirecek miyim?
- Zorunlu olmalı mı?
Bu dört sorudan herhangi birine evet diyorsanız cevap nettir: filtrelenecek, sıralanacak, ilişkilendirilecek veya zorunlu olacak her veri normal bir sütun olmalıdır — JSON yalnızca bunların hiçbirinin gerekmediği veriler içindir.
Bu test, çoğu kararı saniyeler içinde verdirir.
Emin değilseniz sütun tercih edin; sonradan JSON'a taşımak, JSON'dan sütuna çıkarmaktan kolaydır.
Dördüncü madde ise veri bütünlüğü açısından belirleyicidir.
Karma Yaklaşım
- Bilinen ve sorgulanan alanlar sütun.
- Değişken ve nadir alanlar JSON.
- Sınır zamanla ayarlanır.
Üçüncü madde pratik bir evrim yolu sunar: JSON içindeki bir alan sık sorgulanmaya başladığında onu ayrı bir sütuna taşımak doğal bir olgunlaşmadır — başlangıçta esneklik, sonrasında yapı kazanılır.
Bu geçiş sırasında mevcut kayıtlar için değer doldurulmalıdır.
Bu karma yaklaşım, iki dünyanın avantajlarını birleştirir.
Önemli olan, sınırın bilinçli çizilmesi ve belgelenmesidir.
Veritabanı performansını izleyip sorgu davranışını ölçebilmek gerekir; sanal sunucu kiralama paketleri ile tam yetkili erişim sayesinde sorgu planlarını doğrudan inceleyebilirsiniz.
Sonuç
JSON alanların doğru kullanımı dardır ama gerçektir: sorgulanmayan, yalnızca saklanan veriler için idealdir — bir ödeme sağlayıcısının tam yanıtı gibi. Ama JSON içindeki bir değere göre filtrelemek, veritabanının her satırda o yapıyı ayrıştırması demektir ve büyük tablolarda kabul edilemez biçimde yavaştır. Karar testi basit: filtrelenecek, sıralanacak, ilişkilendirilecek veya zorunlu olacak her veri normal bir sütun olmalıdır.
Sıkça Sorulan Sorular (SSS)
JSON alanı ne zaman kullanmalıyım?
Sorgulanmayan, yalnızca saklanıp gerektiğinde okunan veriler için. En doğru kullanım, bir dış servisin döndürdüğü tam yanıtı olduğu gibi saklamaktır — ileride bir uyuşmazlıkta ne alındığını kanıtlar ve o yapının değişmesi sizi etkilemez.
JSON içindeki değere göre filtreleyebilir miyim?
Filtreleyebilirsiniz ama pahalıdır — veritabanı her satırda yapıyı ayrıştırıp değeri çıkarmak zorundadır. Dizin eklemek mümkündür ama bunun için değeri ayrı bir sütuna çıkarmanız gerekir; o hâlde en baştan sütun kullanmak daha basit olurdu.
JSON alanında veri kaybı yaşanır mı?
Yaşanabilir. İki işlem aynı alanın farklı anahtarlarını güncelliyorsa ve her ikisi de tüm alanı okuyup geri yazıyorsa, ikinci yazma birincinin değişikliğini siler. Bu kayıp hata vermez ve fark edilmesi çok zordur. Veritabanının JSON güncelleme fonksiyonlarını kullanın.
Şema göçünden kurtuluyor muyum?
Hayır, göç ortadan kalkmaz — veritabanından koda taşınır. Artık her okuma noktasında alanın var olup olmadığını kontrol etmek zorundasınız ve bu kontrol unutulduğunda hata çıkar. Veritabanı göçü açık ve tek yerdedir; kod içi kontroller dağınıktır.