2012-07-16 32 views
8

Zastanawiam się nad idealną strukturą dokumentu dla maksymalnej wydajności zapytań dla różnych sytuacji i jest jedna, o którą chcę zapytać. To naprawdę wynikało ze mnie, nie bardzo wiedząc, jak MongoDB zachowuje się w pamięci w tym szczególnym przypadku. Podam hipotetyczny scenariusz.Co to jest dobra struktura dokumentów MongoDB do najskuteczniejszych zapytań użytkowników/followeesów?

Wyobraź sobie system obserwatorów i Followees w stylu Twitter. Po pobieżnym spojrzeniem wprawdzie, główne opcje wydają się być:

  1. W każdym dokumencie użytkownika, „wyznawcy” tablica zawierająca odnośniki do wszystkich dokumentów z innymi użytkownikami one nastąpią. Followees można znaleźć, znajdując naszego obecnego użytkownika w tablicy "user.followers" innych użytkowników. Główną wadą wydaje się być potencjalne obciążenie zapytania wyszukiwania Followee. Ponadto, w przypadku zapytania dotyczącego zawartości "user.followers", MongoDB po prostu uzyskuje dostęp do wymaganego pola w dokumentach użytkowników lub odnaleziono cały dokument użytkownika, a następnie odczytywane są wymagane wartości pól i są one buforowane/przechowywane w taki sposób, że zapytanie w dużej bazie użytkowników wymagałoby znacznie więcej pamięci?

  2. W każdym dokumencie użytkownika, przechowującym zarówno "obserwatorów" i "followees" dla szybszego dostępu do każdego. To oczywiście ma wadę duplikatów danych w tym sensie, że wpis dla użytkownika A następujący użytkownik B istnieje w obu dokumentach użytkownika w odpowiednim polu, a usunięcie z od wymaga dopasowania usunięcia w drugim. Z technicznego punktu widzenia może to oznaczać podwojenie liczby punktów potencjalnego niepowodzenia w przypadku zwykłego usunięcia. A czy MongoDB nadal cierpi z powodu tego, co usłyszałem, określanego jako "szwajcarskie cheesing" z jego danych przechowywanych w pamięci, kiedy pojawiają się skreślenia, a zatem usunięcie z 2 pól zamiast 1 podwaja efekt tego problemu z dziurami pamięci?

  3. Osobna kolekcja do przechowywania informacji o użytkownikach, w podobny sposób odpowiadająca dokumentom użytkownika w punkcie 1, z wyjątkiem tego, że oczywiste jest, że jedynymi dostępnymi danymi są Obserwatorzy, więc jeśli dokumenty użytkownika zawierają sporo innych danych związanych z każdego użytkownika, unikamy dostępu do tych danych. Wydaje się, że ma to coś z relacyjnej bazy danych i chociaż wiem, że nie zawsze jest to straszne podejście, z zasady, oczywiście jeśli jedno z innych podejść wymienionych (lub jedno, którego nie rozważałem) jest lepsze w architekturze Mongo "Chciałbym się uczyć!

Jeśli ktoś ma jakieś przemyślenia na temat tego, czy chce mi powiedzieć Tęskniłam bardzo istotne i oczywiste stronę docs i gdzieś, a nawet chce mi powiedzieć, że jestem po prostu głupi (myślał o wyjaśnienie, dlaczego, proszę;)) Chciałbym usłyszeć od ciebie!

+0

Jakiego języka programowania będziesz używać? W zależności od tego, istnieją pewne funkcje, które mogą być obsługiwane przez sterownik podstawowy. W szczególności mówię o DBRefs. http://docs.mongodb.org/manual/applications/database-references/ –

+0

To dobra uwaga, dzięki. Moglibyśmy w końcu użyć czegokolwiek, ale obecnie jest to połączenie PHP i Node.js. – tdous

Odpowiedz

7

Jest to klasyczny problem wyznawca-followee i nie ma jednej odpowiedzi na it..Check na ten link:

mongo db design of following and feeds, where should I embed?

Faktycznie sytuacja ta nadaje się bardzo dobrze do relacyjnej schematu, jeśli MongoDB i SQL serwer były jedynymi wyborami, które miałeś. Jest to jednak szczególny rodzaj problemu relacyjnego, w którym istnieje dwukierunkowy związek.To może być może być lepiej obsługiwane przez bazę danych wykresu:

http://forum.kohanaframework.org/discussion/10130/followers-and-following-database-design-like-twitter/p1

Chodzi o to, można je zachować zwolenników i followees w dokumencie użytkownika, ale nie oba, dla uniknięcia problemów podwójne usunięcie. Więc jeśli musisz trzymać się MongoDB, jednym wyjściem może być .. (zakładając, że ludzie nie śledzą/nie obserwują nikogo, często),),

Zachowaj tylko followees w dokumencie, ponieważ kiedy przeglądam mój profil, byłbym zainteresowany ludzi śledzę .. (to jest powodem, że w ślad za nimi w pierwszej kolejności, prawda?) .. a potem zrobić kwerendę jak:

db.Users.find({ user_id : { $in : followees })

Dzięki temu dowiesz się, którzy wszyscy są następujące ja (powiedzmy, że mój identyfikator to "user_id").
Innym powodem, dla którego nie sugeruję odwrotnie, jest to, że ... można obserwować maksymalnie 30-40 osób, więc dokument użytkownika przechowujący od 30 do 40 followanych powinien być w porządku w stosunku do dokumentu użytkownika przechowującego tysiące Obserwujący! Z podejściem "followee-in-document" otrzymujesz dokumenty o rozmiarach w przybliżeniu o wielkości. W podejściu "follower-in-document" będziesz miał również bardzo małe, ale również bardzo nieporęczne dokumenty. I w zależności od ilości danych, które umieścisz (jeśli są, z wyjątkiem follower_id), możesz chcieć zachować ostrożność w kwestii limitu rozmiaru dokumentu.

+1

Nice! Obejmowałeś wszystkie punkty, które miałem do powiedzenia! Opcja 2 to zdecydowanie nie nie. Przechowywanie identyfikatorów użytkowników, których obserwujesz, jest drogą do zrobienia. Uzyskanie listy użytkowników, którzy Cię śledzą, jest tylko jednym zapytaniem i może być indeksowane. Patrz: http://www.mongodb.org/display/DOCS/Schema+Design –

+0

Tak też uważam, ale jestem nieco zaniepokojony problemem wydajności "bezgranicznego pola" w mongo, który może sprawiają, że jest to kiepski wybór. Zobacz: http://stackoverflow.com/questions/9306815/mongodb-performance-with-growing-data-structure Jakie są Twoje przemyślenia na ten temat? – UpTheCreek

+0

@UpTheCreek Pole bez ograniczeń jest tutaj listą obserwowanych elementów. Zakładając, że liczba ta nie wzrośnie powyżej 30-40 użytkowników, będzie to mniejszy problem niż posiadanie nieograniczonego pola zawierającego tysiące obserwujących. Znowu ten argument jest bardzo specyficzny dla tego przypadku użycia (follower-followee in twitter style). –

2

Biorąc pod uwagę, że jest to wiele do wielu relacji, opcja (2) dobrze mi wygląda. Jeśli chodzi o pasujące skreślenia, zwykle nie jest to problemem, o ile istnieje jakiś mechanizm uzgodnienia między tymi dwoma dokumentami.

Fragmentacja zależy zasadniczo od wzorców dostępu aplikacji i generalnie jest problemem w większości systemów danych. Wprowadzono kilka znaczących zmian w mongo, aby uniknąć wewnętrznej fragmentacji. Co więcej, istnieją alternatywy kompaktowania w trybie offline, aby naprawić fragmentację, jeśli tak się stanie.