MongoDB Şema Tasarımı - Çok sayıda küçük belge mi yoksa daha az sayıda büyük belge mi?


89

Arka Plan
RDBMS veritabanımızdan MongoDB'ye bir dönüşümün prototipini oluşturuyorum. Normalden arındırırken, sanki iki seçeneğim varmış gibi görünüyor; biri çok sayıda (milyonlarca) daha küçük belgeye yol açıyor veya diğeri daha az (yüz binlerce) büyük belgeye yol açıyor.

Basit bir analoga indirgeyebilseydim, bunun gibi daha az Müşteri belgesine sahip bir koleksiyon arasındaki fark olurdu (Java'da):

sınıf Müşteri {
    özel Dize adı;
    özel Adres adresi;
    // her CreditCard'ın yüzlerce Ödeme örneği vardır
    özel Set <CreditCard> kredi kartları;
}

veya bunun gibi birçok Ödeme belgesine sahip bir koleksiyon:

class Payment {
    özel Müşteri müşteri;
    özel CreditCard kredi kartı;
    özel Ödeme Tarihi;
    özel kayan nokta payAmount;
}

Soru
MongoDB, çok sayıda küçük belgeyi veya daha az sayıda büyük belgeyi tercih edecek şekilde mi tasarlandı? Cevap çoğunlukla hangi sorguları çalıştırmayı planladığıma bağlı mı? (yani X müşterisinin kaç kredi kartı var? vs Tüm müşterilerin geçen ay ödediği ortalama tutar neydi?)

Etrafıma çok baktım ama sorumu cevaplamama yardımcı olacak en iyi MongoDB şeması uygulamalarına rastlamadım.

Yanıtlar:


82

Yaptığınız sorgular için kesinlikle optimizasyon yapmanız gerekecek.

İşte açıklamanıza göre en iyi tahminim.

Muhtemelen her Müşteri için tüm Kredi Kartlarını bilmek isteyeceksiniz, bu nedenle Müşteri Nesnesi içinde bir dizi bulundurun. Ayrıca muhtemelen her Ödeme için bir Müşteri referansına sahip olmak isteyeceksiniz. Bu, Ödeme belgesini nispeten küçük tutacaktır.

Ödeme nesnesi otomatik olarak kendi kimliğine ve dizine sahip olacaktır. Muhtemelen Müşteri referansına da bir dizin eklemek isteyeceksiniz.

Bu, her seferinde tüm müşteri nesnesini depolamadan Müşteri Tarafından Ödemeleri hızlı bir şekilde aramanıza olanak tanır.

"Geçen ay tüm müşterilerin ödediği ortalama tutar neydi" gibi soruları yanıtlamak istiyorsanız, bunun yerine herhangi bir büyük veri kümesi için bir harita / indirim isteyeceksiniz. Bu yanıtı "gerçek zamanlı" alamıyorsunuz. Müşteriye bir "referans" kaydetmenin bu harita indirimleri için muhtemelen yeterince iyi olduğunu göreceksiniz.

Yani sorunuzu doğrudan yanıtlamak için: MongoDB, çok sayıda küçük belgeyi veya daha az sayıda büyük belgeyi tercih edecek şekilde mi tasarlandı?

MongoDB, indekslenmiş girişleri çok hızlı bulmak için tasarlanmıştır. MongoDB, büyük bir samanlıkta birkaç iğne bulmada çok iyidir . MongoDB samanlıktaki iğnelerin çoğunu bulmakta pek iyi değil . Bu nedenle, verilerinizi en yaygın kullanım durumlarınız etrafında oluşturun ve daha nadir kullanım durumları için harita yazın / işleri azaltın.


32

MongoDB'nin kendi belgelerine göre, birçok küçük belge için tasarlanmış gibi görünüyor.

Gönderen MongoDB performans En İyi Uygulamalar :

MongoDB'deki belgeler için maksimum boyut 16 MB'dir. Pratikte çoğu belge birkaç kilobayt veya daha azdır. Belgeleri, tabloların kendisinden çok bir tablodaki satırlara benzetiniz. Kayıt listelerini tek bir belgede tutmak yerine, her kaydı bir belge yapın.

Gönderen Bölüm 1: MongoDB Şema Tasarım İçin Pratik 6 Kuralları :

Bire Birkaç Modelleme

Bir kişinin adresleri "bire az" örneğidir. Bu, yerleştirme için iyi bir kullanım örneğidir - adresleri Person nesnenizin içindeki bir diziye koyarsınız.

Bire Çok

"Birden çoğa" örneğine bir örnek, yedek parça sipariş sistemindeki bir ürünün parçaları olabilir. Her ürün birkaç yüz yedek parçaya sahip olabilir, ancak hiçbir zaman birkaç bini geçmez. Bu, referans için iyi bir kullanım örneğidir - parçaların ObjectID'lerini ürün belgesinde bir diziye koyarsınız.

Bire Squillions

Farklı makineler için günlük mesajlarını toplayan bir olay günlüğü sistemi "bire-squillions" örneğidir. Herhangi bir ana bilgisayar, dizide sakladığınız tek şey ObjectID olsa bile, 16 MB'lık belge boyutunu aşmak için yeterli mesaj oluşturabilir. Bu, "ebeveyn referanslama" için klasik kullanım örneğidir - toplantı sahibi için bir belgeniz olur ve ardından ana bilgisayarın Nesne Kimliğini günlük mesajları için belgelerde depolarsınız.


13

Zamanla önemli ölçüde büyüyen belgeler saatli bombalar atıyor olabilir. Ağ bant genişliği ve RAM kullanımı büyük olasılıkla ölçülebilir darboğazlar haline gelecek ve sizi yeniden başlamaya zorlayacaktır.

Öncelikle iki tahsilatı ele alalım: Müşteri ve Ödeme. Bu nedenle, tahıl oldukça küçüktür: ödeme başına bir belge.

Daha sonra, kredi kartları gibi hesap bilgilerini nasıl modelleyeceğinize karar vermelisiniz. Müşteri belgelerinin hesap bilgileri dizileri içerip içermediğini veya yeni bir Hesap koleksiyonuna ihtiyacınız olup olmadığını düşünelim.

Hesap belgeleri müşteri belgelerinden ayrı ise, bir müşterinin tüm hesaplarını belleğe yüklemek, birden çok belgenin alınmasını gerektirir. Bu, fazladan bellek, G / Ç, bant genişliği ve CPU kullanımına dönüşebilir. Bu hemen Hesap koleksiyonunun kötü bir fikir olduğu anlamına mı geliyor?

Kararınız ödeme belgelerini etkiler. Hesap bilgileri bir müşteri belgesine yerleştirilmişse, buna nasıl referans verirsiniz? Ayrı hesap belgelerinin kendi _id özniteliği vardır. Katıştırılmış hesap bilgileriyle, uygulamanız ya hesaplar için yeni kimlikler oluşturur ya da anahtar için hesabın özniteliklerini (ör. Hesap numarası) kullanır.

Bir ödeme belgesi, sabit bir zaman diliminde (ör. Gün?) Yapılan tüm ödemeleri gerçekten içerebilir mi? Bu tür bir karmaşıklık, ödeme belgelerini okuyan ve yazan tüm kodları etkileyecektir. Erken optimizasyon projeler için ölümcül olabilir.

Hesap belgeleri gibi, bir ödeme belgesi yalnızca bir ödeme içerdiği sürece ödemelere kolayca referans verilir. Yeni bir belge türü, örneğin kredi, bir ödemeye atıfta bulunabilir. Ancak bir Kredi tahsilatı mı yaratırsınız yoksa kredi bilgilerini ödeme bilgilerinin içine mi eklersiniz? Daha sonra bir krediye başvurmanız gerekirse ne olur?

Özetlemek gerekirse, birçok küçük belge ve birçok koleksiyonla başarılı oldum. _İd ile ve yalnızca _id ile başvurular gerçekleştiriyorum. Bu nedenle, sürekli büyüyen belgelerin başvurumu yok etmesinden endişelenmiyorum. Şemanın anlaşılması ve indekslenmesi kolaydır çünkü her varlığın kendi koleksiyonu vardır. Önemli varlıklar diğer belgelerin içinde saklanmıyor.

Bulgularınızı duymak isterim. İyi şanslar!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.