MongoDB Schema Design-wiele małych dokumentów czy mniej dużych dokumentów?

Tło
Prototypuję konwersję z naszej bazy danych RDBMS do MongoDB. Podczas denormalizacji wydaje się, że mam dwa wyjścia, jeden, który prowadzi do wielu (milionów) mniejszych dokumentów lub jeden, który prowadzi do mniejszej liczby (setek tysięcy) dużych dokumentów.

Gdybym mógł sprowadzić to do prostego analogu, byłaby to różnica między zbiorem z mniejszą liczbą dokumentów Klienta, takich jak ten (w Javie):

class Customer {
    private String name;
    private Address address;
    // each CreditCard has hundreds of Payment instances
    private Set<CreditCard> creditCards;
}

Lub zbiór z wieloma, wiele takich dokumentów płatności:

class Payment {
    private Customer customer;
    private CreditCard creditCard;
    private Date payDate;
    private float payAmount;
}

Pytanie
Czy MongoDB jest zaprojektowany, aby preferować wiele, wiele małych dokumentów czy mniej dużych dokumentów? Czy odpowiedź zależy głównie od tego, jakie pytania planuję uruchomić? (czyli ile kart kredytowych ma klient x? vs jaka była średnia kwota zapłacona przez wszystkich klientów w zeszłym miesiącu?)

Rozglądałem się dużo, ale nie natknąłem się na żadne najlepsze praktyki schematu MongoDB, które pomogłyby mi odpowiedzieć na moje pytanie.

Author: Andre, 2010-06-14

3 answers

Na pewno będziesz musiał zoptymalizować dla zapytań, które robisz.

Oto moje najlepsze przypuszczenie na podstawie Twojego opisu.

Prawdopodobnie będziesz chciał znać wszystkie karty kredytowe dla każdego klienta, więc zachowaj tablicę tych w obiekcie klienta. Prawdopodobnie będziesz również chciał mieć referencje klienta dla każdej płatności. Dzięki temu dokument płatności będzie stosunkowo mały.

Obiekt płatności będzie automatycznie miał swój własny identyfikator i indeks. Prawdopodobnie będziesz chciał dodać indeks na referencji Klienta, jak również.

Pozwoli Ci to na szybkie wyszukiwanie płatności przez Klienta bez każdorazowego przechowywania całego obiektu klienta.

Jeśli chcesz odpowiedzieć na pytania typu "jaka była średnia kwota zapłacona przez wszystkich klientów w zeszłym miesiącu" zamiast tego będziesz chciał mapę / zmniejszyć dla każdego dużego zbioru danych. Nie dostaniesz tej odpowiedzi "w czasie rzeczywistym". Przekonasz się, że przechowywanie "odniesienia" do klienta jest prawdopodobnie wystarczająco dobre dla tych Mapa-zmniejsza.

Więc odpowiadając bezpośrednio na twoje pytanie: Czy MongoDB jest zaprojektowany, aby preferować wiele, wiele małych dokumentów lub mniej dużych dokumentów?

MongoDB jest przeznaczony do szybkiego wyszukiwania indeksowanych wpisów. MongoDB jest bardzo dobry w znajdowaniu kilku igieł w dużym stogu siana. MongoDB jest nie Bardzo dobry w znajdowaniu większości igieł w stogu siana. Twórz dane w oparciu o najczęstsze przypadki użycia i twórz mapy/redukuj zadania do rzadszego użycia sprawy.

 84
Author: Gates VP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-22 04:10:50

Według własnej dokumentacji MongoDB, wygląda na to, że został zaprojektowany dla wielu małych dokumentów.

Z najlepsze praktyki wydajności dla MongoDB :

Maksymalny rozmiar dokumentów w MongoDB to 16 MB. W praktyce większość dokumenty mają kilka kilobajtów lub mniej. Rozważ dokumenty bardziej jak wiersze w tabeli niż same tabele. Zamiast utrzymywać listy rekordów w jednym dokumencie, zamiast tego sprawiają, że każdy rekord dokument.

Z 6 zasad projektowania schematów MongoDB: Część 1:

Modelowanie jeden do kilku

Przykładem" jeden do kilku " mogą być adresy danej osoby. To jest dobrym przykładem użycia do osadzania-umieściłbyś adresy w tablicy wewnątrz obiektu osoby.

One-to-Many

Przykładem" jeden do wielu " mogą być Części do produktu w system zamawiania części zamiennych. Każdy produkt może mieć do kilku sto części zamiennych, ale nigdy więcej niż kilka tysięcy lub więc. Jest to dobry przypadek użycia w odniesieniu do – można umieścić przedmiot z części w tablicy w dokumencie produktu.

One-to-Squillions

Przykładem "jeden do squillions" może być system rejestrowania zdarzeń który zbiera wiadomości dziennika dla różnych maszyn. Dowolny host może wygenerować wystarczającą ilość wiadomości, aby przepełnić rozmiar dokumentu 16 MB, nawet jeśli wszystko, co zapisałeś w tablicy, to obiekt. To jest classic use case for "parent-referencing" – będziesz miał dokument dla hosta, a następnie przechowywać obiekt hosta w dokumentach dla wiadomości dziennika.

 33
Author: bmaupin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-25 13:28:24

Dokumenty, które znacznie rosną w czasie, mogą być tykającymi bombami zegarowymi. Przepustowość sieci i wykorzystanie pamięci RAM prawdopodobnie staną się wymiernymi wąskimi gardłami, zmuszając cię do rozpoczęcia pracy od nowa.

Najpierw rozważmy dwie kolekcje: klient i płatność. Tak więc ziarno jest dość małe: jeden dokument na Płatność.

Następnie musisz zdecydować, jak modelować informacje o koncie, takie jak karty kredytowe. Zastanówmy się, czy dokumenty klienta zawierają tablice informacji o koncie, czy potrzebujesz nowy zbiór kont.

Jeśli dokumenty konta są oddzielone od dokumentów klienta, załadowanie wszystkich kont dla jednego klienta do pamięci wymaga pobrania wielu dokumentów. Może to przekładać się na dodatkową pamięć, I / O, przepustowość i wykorzystanie procesora. Czy to od razu oznacza, że zbieranie konta to zły pomysł?

Twoja decyzja ma wpływ na dokumenty płatności. Jeśli informacje o koncie są osadzone w dokumencie klienta, w jaki sposób można się do niego odwołać? Osobne dokumenty konta mają własny atrybut _id. Dzięki osadzonym informacjom o koncie aplikacja wygeneruje nowe identyfikatory dla kont lub użyje atrybutów konta (np. numeru konta) dla klucza.

Czy dokument płatności może rzeczywiście zawierać wszystkie płatności dokonane w ustalonych ramach czasowych(np. dzień?). Taka złożoność wpłynie na cały kod, który odczytuje i zapisuje dokumenty płatności. Przedwczesna optymalizacja może być śmiertelna dla projektów.

Podobnie jak dokumenty konta, płatności można łatwo określić tak długo, jak długo ponieważ dokument płatności zawiera tylko jedną płatność. Nowy rodzaj dokumentu, na przykład kredyt, może odwoływać się do płatności. Ale czy utworzyłbyś kolekcję kredytową, czy umieściłbyś informacje kredytowe w informacjach o płatnościach? Co by się stało, gdybyś później musiał odwołać się do kredytu?

Podsumowując, odniosłem sukces z wieloma małymi dokumentami i wieloma zbiorami. Implementuję referencje z _id i tylko z _id. Nie przejmuję się więc ciągle rosnącym niszczeniem dokumentów moje podanie. Schemat jest łatwy do zrozumienia i indeksowania, ponieważ każdy element ma swoją własną kolekcję. Ważne podmioty nie ukrywają się w innych dokumentach.

Chciałbym usłyszeć o twoich odkryciach. Powodzenia!

 14
Author: Terris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-18 19:39:31