Çalışan yazılımcılar için MongoDB’de veri modelleme, sorgu optimizasyonu, indeks stratejileri ve ölçekleme pratikleri. Gerçek dünya örnekleri ve kodlarla verimli geçiş yolları.
MongoDB ile Gerçek Dünya Uygulamaları: Modelleme ve Performans İpuçları
Bu makalede MongoDB kullanırken sık karşılaşılan gereksinimler için veri modelleme yaklaşımlarını, indeksleme stratejilerini, sorgu optimizasyonlarını ve yatay ölçekleme pratiklerini gerçek dünya örnekleriyle ele alacağız. Hedef kitle çalışan yazılımcılar; örnekler Node.js/JavaScript ekosistemi odaklı ama prensipler her dil için geçerli.
Neden MongoDB? Ne zaman tercih edilir?
MongoDB, belge tabanlı (document) bir NoSQL veritabanıdır. JSON-benzeri BSON formatı, esnek şema yapısı ve zengin doküman modelleri sayesinde hızlı prototipleme, sık değişen şemalar ve hiyerarşik verilerin saklanması için uygundur. Geleneksel ilişkisel veritabanlarının (RDBMS) zorlandığı bazı problemler için daha doğal çözümler sunar.
Ancak her durum MongoDB için ideal değildir. ACID gerektiren karmaşık çok tablolu işlemler, güçlü ilişkisel bütünlük veya olgun raporlama gereksinimleri varsa ilişkisel veritabanları hâlâ daha uygun olabilir. Doğru tercih uygulamanın gereksinimlerine, sorgu profiline ve büyüme beklentisine bağlıdır.
Veri modelleme: Embed mi, Reference mı?
MongoDB’de aynı veriyi temsil etmenin iki temel yolu vardır: embedding (gömme) ve referencing (referans). Hangi yöntemi seçtiğiniz performans, tutarlılık ve sorgu karmaşıklığını doğrudan etkiler. Genel kural: sık birlikte okunup yazılan ve boyutu makul olan ilişkileri embed edin; sık bağımsız güncellenen büyük ilişkiler için referans kullanın.
Örnek: Bir e-ticaret sipariş modelinde ürün detaylarını doğrudan sipariş dokümanı içinde saklamak (embed) sipariş geçmişini hızla okumayı sağlar. Ancak ürün fiyatı veya stok bilgisi sıklıkla güncelleniyorsa, ürünleri ayrı koleksiyonda tutup siparişte yalnızca referans (productId) ve snapshot bilgiler (fiyat, isim) saklamak daha sağlıklıdır.
<!-- Örnek: Embed (order içinde items) -->
{
"_id": "order123",
"userId": "user456",
"items": [
{ "productId": "p1", "name": "Kamera", "price": 1200, "qty": 1 },
{ "productId": "p2", "name": "Tripod", "price": 200, "qty": 1 }
],
"total": 1400
}
<!-- Örnek: Reference -->
{ "_id": "order123", "userId": "user456", "items": [{ "productId": "p1", "qty": 1 }], "total": 1400 }
İndeksleme stratejileri ve performans
İyi bir indeksleme stratejisi sorgu performansını dramatik şekilde artırır. MongoDB'de tek alan indeksleri, bileşik indeksler, metin indeksleri, zaman serisi indeksleri ve geospatial indeksler gibi seçenekler vardır. Sorgu deseninizi analiz edip en çok kullanılan filtre ve sıralama alanlarına göre indeks oluşturun.
Bileşik indeksler (compound indexes) oluştururken sorgularınızın hangi alanları kullanacağını ve alanların sırasını düşünün. Sorguda filter sonra sort kullanılan alanların sırası indeksin etkisini belirler. Ayrıca, gereksiz indekslerden kaçının; her indeks yazma maliyeti getirir.
// Node.js MongoDB sürücüsü örneği: bileşik indeks oluşturma
await db.collection('orders').createIndex({ userId: 1, createdAt: -1 });
// Sık kullanılan bir filtre ve sıralama kombinasyonu için uygundur
db.orders.find({ userId: 'user456' }).sort({ createdAt: -1 });
Sorgu optimizasyonu ve explain kullanımı
Sorgu yavaş çalıştığında ilk adım explain() ile sorgu planını incelemektir. explain, hangi indeksin kullanıldığını, taranan doküman sayısını ve aşamaları gösterir. Buna göre indeks ekleyebilir, sorguyu yeniden yazabilir veya projeksiyonla gereksiz alanları göndermeyi engelleyebilirsiniz.
Projeksiyon (projection) ile sadece ihtiyacınız olan alanları döndürmek ağ ve bellek kullanımını azaltır. Büyük dokümanlardan sadece birkaç alan gerektiğinde mutlaka projection kullanın. Ayrıca aggregation pipeline’da $match aşamasını mümkün olduğunca pipeline başına koyun; böylece sonraki aşamalar daha az veriyle çalışır.
// explain örneği (mongo shell)
db.orders.find({ total: { $gt: 100 } }).explain('executionStats');
// projection örneği
db.users.find({ active: true }, { name: 1, email: 1 });
Ölçekleme: Replika set ve Sharding
MongoDB ölçeklenebilirlik için iki temel yöntem sunar: replika setler ve sharding. Replika setler yüksek erişilebilirlik ve okuma replikasyonu sağlar; primär node yazma işlemlerini yaparken sekonderler okuma için kullanılabilir. Sharding ise veri kümesini yatay bölerek çok büyük veri ve yüksek yazma yüklerini dağıtmaya yarar.
Sharding kararını uygulama mimarisi ve veri erişim desenine göre verin. İyi bir shard key seçimi kritik önemdedir: yüksek kardinalite, iyi dağılım ve sık kullanılan sorgularda yer alması gerekir. Yanlış shard key hot-spot’lara ve dengesiz yüklenmeye yol açar.
Operasyonel pratikler: Backup, monitoring ve bakım
Canlı sistemlerde düzenli backup ve izleme şarttır. MongoDB Ops Manager, Cloud Manager veya açık kaynak araçlar (Prometheus + Grafana) ile izleme kurulumu yapın. Replica set durumunu, oplog büyüklüğünü, sorgu gecikmelerini ve indeks kullanımını takip edin.
Bakım sırasında indeks yeniden oluşturma, veri sıkıştırma (wiredTiger) gibi işlemler sistemde etki yaratır. Bu tür işlemleri düşük trafikli zamanlara planlayın ve rollback prosedürlerini hazır bulundurun. Ayrıca sürüm yükseltmelerini test ortamında mutlaka denedikten sonra prodüksiyona taşıyın.
Geçiş: İlişkisel Veritabanından MongoDB’ye taşınma
Legacy uygulamaları MongoDB’ye taşırken doğrudan birebir tablo -> koleksiyon çevirisi çoğu zaman iyi sonuç vermez. Veri modelini yeniden düşünün: ilişkileri embed ederek sorgu sayısını azaltın veya referanslama ile tutarlılığı sağlayın. Denormalizasyonu bilinçli yapın; bazı veri tekrarları kabul edilebilir performans kazançları sağlar.
ETL sürecinde dikkat edilmesi gerekenler: veri tipi dönüşümleri, referans tutarlılığı, transactional sınırlar ve eski uygulama kodunun uyarlanması. Büyük veri setleri için toplu import (mongoimport, mongorestore) araçları kullanılırken indeksleri sonradan oluşturmak import hızını artırır.
Sık Sorulan Sorular
1) MongoDB’de transaction desteği var mı, nasıl kullanmalıyım?
MongoDB 4.0 ile çok-dokümanlı ACID transaction desteği geldi (replica set içinde) ve 4.2 ile sharded cluster’larda da desteklendi. Ancak transactions performans maliyeti getirir; mümkünse tek doküman atomikliği ve iyi modelleme ile transaction ihtiyacını azaltın. Gerektiğinde resmi sürücülerin transaction API’lerini kullanın.
2) Index kullanımı fazla mı olmalı, kaç indeks makul?
İndeks sayısı uygulamaya göre değişir ama her indeks yazma maliyeti getirir. Sorgu performansını belirgin şekilde iyileştiren indeksleri önceliklendirin. Kullanılmayan indeksleri tespit için monitoring araçları ve explain sonuçlarını inceleyin; gereksiz indeksleri kaldırın.
3) Shard key seçerken en sık yapılan hata nedir?
En sık yapılan hata düşük kardinaliteli veya monoton artan alanları shard key yapmak (ör. createdAt tek başına). Bu durum hot-spot oluşturur. İyi shard key yüksek dağılım ve sorgu desenleriyle uyumlu olmalı; bazen compound shard key daha uygundur.
İlgili Eğitim
Sonuç
MongoDB, doğru kullanıldığında geliştiricilere esneklik ve yüksek performans sunar. Başarının anahtarı doğru veri modelleme, uygun indeksleme, sorgu optimizasyonu ve operasyonel uygulamalardır. Taşıma veya yeni projelerde karar verirken uygulama ihtiyaçlarını dikkatle analiz edin; gerektiğinde hibrit çözümler (hem RDBMS hem MongoDB) tercih edilebilir. Makalede verilen pratikler real-world senaryolara yöneliktir; kendi uygulamanızda bu prensipleri deneyin ve explain/monitoring ile sürekli iyileştirme yapın.
