Doküman Modelleme — Göm mü, Referans mı?
Önce şunu oku: SQL mi, NoSQL mi? — Önce Erişim Desenini Yaz
30 saniyede özet
Doküman veritabanında en büyük karar şu: ilgili veriyi aynı dokümanın içine mi koyacaksın, ayrı tutup bağlantı mı vereceksin? Birlikte okunan ve sınırlı olan içeri girer; sınırsız büyüyen dışarıda durur.
Blog platformu yorumları yazının içine gömdü; tek sorguyla sayfa açılıyordu. Sonra bir yazı viral oldu.
-
Bayt: Yorumları yazının içine gömdük. Sayfa tek sorguyla açılıyor!
-
Sen: Kulağa harika geliyor.
-
Bayt: Sonra bir yazı viral oldu ve yorumlar akmaya başladı...
-
Bayt: Birlikte okunan birlikte durur. Ama sınırsız büyüyen de mi?
Birlikte okunan birlikte durur
İlişkisel modelde veri önce normalize edilir, sorgu sonra düşünülür. Doküman modelinde sıra terstir: önce uygulamanın veriyi nasıl okuduğuna bakılır.
gömmeDoküman modelinde ilişkili veriyi ayrı bir koleksiyon yerine ana dokümanın içine koymak. Birlikte okunan ve sınırlı veri için tek okuma ve atomik yazma sağlar.Sözlükte gör →, ilişkili veriyi ana dokümanın içine koymaktır. Sipariş ve kalemleri hep birlikte okunur ve birlikte oluşturulur; tek dokümanda durdukları için tek okuma ve tek atomik yazma yeter.
Kafam karıştı, daha basit anlat
Birlikte okuduğun şeyleri aynı zarfa koy. Sipariş ve kalemleri hep birlikte okunuyorsa, tek bir dokümanda durmaları en hızlısıdır.
MongoDB'de sipariş kalemlerini siparişin içine gömmenin en büyük kazancı nedir?
Sınırsız büyüyen gömülmez
Yorumlar yazının içinde bir dizide duruyor. Yazı viral oluyor ve yorum sayısı on binleri geçiyor. Ne olur? Cevabı göster
Doküman büyür ve her yorum onu yeniden yazar. MongoDB’de bir dokümanın üst sınırı 16 MB’tır. Sınıra gelmeden de her okuma ve güncelleme büyük dokümanı taşımak zorunda kalır.
Adım adım oku
- Birlikte okunan ve sınırlı kalan veri, yazının başlığı ve etiketleri gibi, aynı dokümanda durur.
- Yorumlar da yazının içine bir dizi olarak konur.
- Yorumlar sınırsız büyür: her yeni yorum dev dokümanı baştan yazdırır ve doküman boyut sınırına dayanır.
- Sınırsız büyüyen veri ayrı bir koleksiyonda tutulur; her yorum yazıya yalnızca bir kimlikle bağlanır.
Kural basit: dizinin üst sınırını söyleyemiyorsan onu gömme. Siparişin kalemleri sınırlıdır; bir yazının yorumları, bir kullanıcının log kayıtları sınırsızdır.
Kafam karıştı, daha basit anlat
Zarfa sonsuza kadar kâğıt eklenebiliyorsa bir gün yırtılır. Kaç tane olacağını bilmediğin şeyleri gömme, ayrı bir yerde tut.
Bir kullanıcının bütün aktivite log'larını kullanıcı dokümanında bir dizide tutmanın riski nedir?
Her ilişkiyi gömmeye mi yoksa ayrı koleksiyona mı daha uygun olduğuna göre ayır.
Kendin gör
Göm mü, referans mı?
Tohum 163480{ _id, title, body, comments: [ …tüm yorumlar… ] }- Yazı sayfası: yazı ve son 10 yorum
- Popüler bir yazıya on binlerce yorum geliyor
- Bir kullanıcının bütün yorumları
Şu an ne oldu?
Blog yazısı → yorumlar: Göm
Uygulamanın ihtiyaçları tek tek bu modele karşı denenecek.
Görevler0/3
Sınırsız büyüyen bir diziyi gömaçık
İpucu
Popüler bir yazının yorumları.
Eski faturaların yeni adresi göstermesine yol açaçık
İpucu
Her şeyi tek bir güncel kaynaktan okumak.
Yorumlar için bütün ihtiyaçları uygun hâle getiraçık
İpucu
Ne tamamen göm, ne tamamen ayır.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat. Bütün yorumlar gömülü: popüler yazı ve kullanıcı sorguları sorunlu.
- Referansa geç. Büyüme sorunu bitti, ama sayfa iki sorgu istiyor.
- Karma modeli seç. Son 10 yorum yazıda, gerisi ayrı: hepsi uygun.
- Sipariş → müşteri, referans. Eski faturalar yeni adresi gösteriyor.
- Aynı ilişkide karma. Ad ve adres kopyalandı, e-posta tek yerde.
Simülatörde sipariş → müşteri ilişkisi tamamen referansla tutulunca fatura ihtiyacı 'sorunlu' çıktı. Neden?
Arada kalan yollar
Çoğu gerçek model ne tamamen gömülü ne tamamen ayrıdır.
- subset patternSık okunan sınırlı bir parçayı (ör. son 10 yorum) ana dokümana gömüp tamamını ayrı koleksiyonda tutan doküman modelleme kalıbı.Sözlükte gör →: en sık okunan sınırlı kısmı (son 10 yorum) göm, tamamını ayrı koleksiyonda tut.
- extended referenceReferansın yanına ilgili dokümanın sık okunan birkaç alanının kopyasını koymak (ör. müşteri id'si ve adı). Okumayı ucuzlatır, kopyaların güncelliğini yönetmeyi gerektirir.Sözlükte gör →: referansın yanına sık okunan birkaç alanın kopyasını koy (müşteri id’si ve adı).
- Anlık kopya: faturadaki adres, sipariş anının kaydıdır; kopyalanması bir hata değil, bir gerekliliktir.
Kopyalanan her alan için sor: bu değer değişirse eski kopyalar güncellenmeli mi, yoksa o anın kaydı olarak mı kalmalı?
Bir banka hesabı bu üç yolu güzelce bir arada gösteriyor. Hesap sahipleri sınırlıdır, hareketler ise yıllarca birikir; bak her biri nereye yerleşiyor.
Derinleş · Banka hesabı: ne gömülür, ne ayrı durur? 4 dosya · ~53 satır · ilk okumada atlayabilirsin
Kafam karıştı, daha basit anlat
Ortası da olur: son on yorumu zarfa koy, hepsini ayrı bir kutuda tut. Böylece sık okunan kısım hızlı gelir, zarf da şişmez.
Sipariş listesinde müşteri adı gösteriliyor ve her liste için müşteri koleksiyonuna ayrıca gitmek pahalı. Hangisi en dengeli çözüm?
Yazı sayfası son 10 yorumu gösteriyor, yorumlar ise sınırsız. Subset pattern nasıl uygulanır?
Tuzaklar
Her yerde $lookup. Her okuma koleksiyonları birleştiriyorsa, ilişkisel bir modeli doküman veritabanında yeniden kurmuşsundur.
Transaction’la modeli kurtarmak. Çok dokümanlı transaction mevcut; ama her iş için gerekiyorsa sınırlar yanlış çizilmiştir.
Sınırsız id dizisi. Takipçi id’lerini kullanıcı dokümanında tutmak, gömülü yorumlarla aynı sorunu yaşar.
Şema sürümü yok. Eski ve yeni biçimdeki dokümanlar yan yana yaşar; bir schemaVersion alanı, okuyan kodun hangisiyle karşılaştığını bilmesini sağlar.
Ünlü kullanıcıların takip isteği yavaşlıyor ve bazıları hata veriyor. Hatalı satır hangisi?
Kendini sına
Doküman modelinde veri, uygulamanın onu nasıl okuduğuna göre şekillenir.
Bir MongoDB uygulamasında neredeyse her sorgu `$lookup` ile üç dört koleksiyonu birleştiriyor ve çoğu yazma çok dokümanlı transaction kullanıyor. Bu ne söylüyor?
Aklında kalacak üç şey
- 1 Birlikte okunan ve birlikte değişen veri tek dokümanda durur: tek okuma, tek seferde yazma.
- 2 Sınırsız büyüyen listeler gömülmez. MongoDB'de bir dokümanın üst sınırı 16 MB'tır ve büyük doküman her güncellemede pahalıdır.
- 3 Kopyalamak bazen hatadır (e-posta), bazen zorunluluktur (faturadaki o günkü adres). Soru şu: bu veri o anın kaydı mı, yoksa hep güncel mi olmalı?
5 kart sonraki derste seni bekliyor