2010-06-10 11 views
22

Będąc jednym z najpopularniejszych rozwiązań NoSQL, MongoDB ma większość zalet tego podejścia. Ale jednym problemem, z którym wciąż walczę, jest to, jak odzwierciedlają relacje między obiektami w magazynie danych NoSQL, a konkretnie - MongoDB.Symulowanie relacji w MongoDB

Na przykład rozważmy prosty model danych: użytkownik, post i komentarz. Jest dla mnie jasne, że komentarze nie mają wartości na własną rękę, a tym samym stają się obiektami osadzonymi na posty. Ale jeśli chodzi o użytkowników - staje się to trudne, ponieważ Użytkownik jest jednostką samą w sobie, nie sprzężoną z Post. Teraz na wypadek, gdyby trzeba było wysyłać posty z pełnymi nazwiskami użytkowników i linkami do profili na stronie internetowej, musiałbym mieć listę postów i informacji o autorze postów (przynajmniej imię i nazwisko).

widzę 2 możliwe rozwiązania tutaj:

  1. De-normalizacji danych w taki sposób, że każdy wpis post zawiera identyfikator jego autora oraz imię i nazwisko (i każdy inny użytkownik przypisuje mogę potrzebować podczas dodawania postów). W ten sposób wysyłanie zapytań o dane byłoby naprawdę proste, ale jeśli użytkownik zaktualizuje swój profil, będę musiał zaktualizować wszystkie posty również przez użytkownika. Ale muszę też przechowywać atrybuty użytkownika w obiektach komentarzy, co oznacza, że ​​aktualizowanie profilu użytkownika zasadniczo wymaga aktualizacji wszystkich wpisów, które mają przynajmniej jeden komentarz użytkownika, chyba że chcę przechowywać komentarze w osobnych kolekcjach.
  2. Przechowuj tylko identyfikator użytkownika w obiekcie postu i wykonaj 2 zapytania: jeden, aby wyświetlić listę wpisów, a drugi, aby wyświetlić listę użytkowników, których identyfikator użytkownika znajduje się na liście autorów postów. Wymaga to 2 zapytań i dodatkowego przetwarzania w moim kodzie aplikacji, aby zmapować użytkowników do postów.

Jestem pewna, że ​​nie jestem pierwszą osobą, która stoi w obliczu tego problemu, ale niestety nie znalazłem żadnych najlepszych praktyk na ten temat do tej pory. Opinie?

+0

Z którym schematem metody korzystałeś? rozwiązanie 1? lub rozwiązanie 2? – koeder

+0

Jest to dość dobrze opisane w odpowiedzi TTT - w zależności od tego, czego potrzebujesz od danych, musisz wybrać. Mam oba podejścia wdrożone w mojej aplikacji. –

+0

Po prostu ciekawa, jak ci się podoba mongotb? Jak twoje doświadczenie używało Mongo? – koeder

Odpowiedz

14

Oba rozwiązania są prawidłowe, zaletą rozwiązania 1 jest to, że można wyświetlić taką stronę, pobierając tylko jeden dokument z bazy danych. Użytkownicy nie aktualizują swojego profilu bardzo często, a po zmianie profilu użytkownika można aktualizować wszystkie posty i wbudowane komentarze asynchronicznie. Możesz indeksować posty i osadzone komentarze na identyfikator użytkownika, aby aktualizacja była szybka. Aktualizacja w mongodb jest bardzo szybka, ponieważ mongodb robi aktualizację w miejscu i nie można wycofywać ani zatwierdzać, więc mongodb nie musi rejestrować zmian.

Jednak użytkownicy na stronach takich jak stackoverflow również mają reputację i ta reputacja zmienia się znacznie bardziej niż ich profil.

Rozwiązanie 2 wymaga pobrania większej liczby dokumentów na stronę, jednak można użyć operatora $ in z listą identyfikatorów użytkownika (identyfikator użytkownika dla wpisu + użytkownika), więc potrzebujesz tylko dwóch "instrukcji wyboru".

1

wychodził podobny problem i to w jaki sposób rozwiązać go:

(Kiedy rozwiązać ten problem, moja jazda motywacją było uniknięcie sprzężeń)

stosowanie 2 oddzielne kolekcja: jeden dla użytkowników i jeden dla POSTS. Przechowuj obiekt użytkownika wraz z postem w kolekcjach postów. Nie aktualizuj kolekcji wpisów po zmianie obiektu użytkownika. Zachowaj informacje o użytkowniku to kolekcja USERS. Oczywiście dane postów będą zawierać nieaktualne informacje o użytkowniku, ale jak często użytkownik zmienia swój profil.

Jeśli musisz wyświetlić absolutne ostatnie informacje o użytkowniku wraz z każdym postem, pobierz informacje o użytkowniku z pamięci podręcznej.

Mam nadzieję, że to zadziała.Moje rozwiązanie jest nadal w fazie rozwoju, więc nie mam wyników testu obciążenia, aby się z Tobą podzielić.