Musisz wziąć pod uwagę rodzaj zapytań, które będziesz musiał wykonać i jak często każdy typ będzie potrzebny. Kiedy pracowałem nad czymś podobnym, wymyśliłem sześć możliwych działań:
- Zrób coś z rodzicem
- Zrób coś z dziećmi
- Zrób coś z przodkami (rodzicami rodziców, rodzicami rodziców rodziców itp.)
- Zrób coś z potomkami (dziećmi dzieci, dziećmi dzieci dzieci itp.)
- Zmień relacje (dodaj/przenieś/usuń węzły w hierarchii)
- Zmień główne dane w bieżącym węźle (np. zmień wartość w polu „tytuł”)
Będziesz chciał oszacować, jak ważny jest każdy z nich dla Twojej aplikacji.
Jeśli większość twojej pracy polega na pracy z przechowywanymi danymi dla danego artykułu, w tym jego bezpośredniego rodzica i dzieci, pierwszy pomysł jest najbardziej przydatny. Rzeczywiście, w MongoDB dość powszechne jest umieszczanie wszystkich potrzebnych informacji w tym samym dokumencie, zamiast odwoływania się do nich zewnętrznie, dzięki czemu wystarczy pobrać tylko jedną rzecz i po prostu pracować z tymi danymi. Ostatnie cztery działania na liście są jednak bardziej skomplikowane.
W szczególności w tym przypadku będziesz musiał przejść przez drzewo, aby pobrać przodków i potomków, przechodząc przez dokumenty pośrednie i podążając ścieżką, nawet jeśli interesuje Cię tylko ostatni dokument na ścieżce. Może to być powolne w przypadku długich hierarchii. Zmiana relacji może wymagać przenoszenia wielu informacji w wielu dokumentach, ponieważ wszystkie dane znajdują się w każdym z nich. Ale nawet zmiana pojedynczego pola, takiego jak „tytuł”, może być denerwująca, ponieważ musisz wziąć pod uwagę fakt, że to pole jest obecne w wielu różnych dokumentach, albo jako pole główne, albo pod polami nadrzędnymi lub podrzędnymi.
Zasadniczo Twój pierwszy pomysł działa najlepiej w większej liczbie aplikacji statycznych gdzie nie będziesz często zmieniać danych po początkowym ich utworzeniu, ale musisz je regularnie czytać.
Dokumentacja MongoDB zawiera pięć zalecanych podejść do obsługi struktur drzewiastych (hierarchicznych). Wszystkie mają różne zalety i wady, chociaż wszystkie ułatwiają aktualizowanie głównych danych w artykule, wystarczy zrobić to w jednym dokumencie.
- Odniesienia dla rodziców :każdy węzeł zawiera odniesienie do swojego rodzica.
- Zalety :
- Szybkie wyszukiwanie nadrzędne (wyszukaj według „_id” =tytuł dokumentu, zwróć pole „rodzic”)
- Szybkie wyszukiwanie dzieci (wyszukaj według „rodzica” =tytuł dokumentu, który zwróci wszystkie dokumenty podrzędne)
- Aktualizacja relacji to tylko kwestia zmiany pola „rodzic”
- Zmiana podstawowych danych wymaga zmian tylko w jednym dokumencie
- Wady :
- Wyszukiwanie według przodków i potomków jest powolne i wymaga przechodzenia
- Odniesienia do dzieci :każdy węzeł zawiera tablicę referencyjną do swoich dzieci
- Zalety :
- Szybkie wyszukiwanie dzieci (zwróć tablicę dzieci)
- Szybka aktualizacja relacji (w razie potrzeby zaktualizuj tablicę dzieci)
- Wady :
- Znalezienie rodzica wymaga wyszukania twojego _id we wszystkich tablicach dzieci wszystkich dokumentów, dopóki go nie znajdziesz (ponieważ rodzic będzie zawierał bieżący węzeł jako dziecko)
- Wyszukiwanie przodków i potomków wymaga przechodzenia przez drzewo
- Zalety :
- Tablica przodków :każdy węzeł zawiera referencję do tablicy swoich przodków i rodzica
- Zalety :
- Szybkie wyszukiwanie przodków (w celu znalezienia konkretnego przodka nie jest wymagane przechodzenie)
- Łatwe wyszukiwanie rodziców i dzieci zgodnie z podejściem „Odniesienia rodzicielskie”
- Aby znaleźć potomków, po prostu wyszukaj przodków, ponieważ wszyscy potomkowie muszą zawierać tych samych przodków
- Wady :
- Musisz się martwić o aktualizowanie tablicy przodków oraz pola nadrzędnego za każdym razem, gdy następuje zmiana relacji, często w wielu dokumentach.
- Zalety :
- Zmaterializowane ścieżki :każdy węzeł zawiera ścieżkę do siebie - wymaga regex
- Zalety :
- Łatwo znaleźć dzieci i potomków za pomocą wyrażenia regularnego
- Może użyć ścieżki do odzyskania rodziców i przodków
- Elastyczność, taka jak znajdowanie węzłów według ścieżek częściowych
- Wady :
- Zmiany relacji są trudne, ponieważ mogą wymagać zmian ścieżek w wielu dokumentach
- Zalety :
- Zestawy zagnieżdżone :Każdy węzeł zawiera pole „lewe” i „prawe”, które pomagają znaleźć poddrzewa
- Zalety :
- Łatwe pobieranie potomków w optymalny sposób, wyszukując „w lewo” i „w prawo”
- Podobnie jak w podejściu „Parent Reference”, łatwo jest znaleźć rodzica i dzieci
- Wady :
- Trzeba przejść przez strukturę, aby znaleźć przodków
- Zmiany relacji działają tutaj najgorzej niż jakakolwiek inna opcja, ponieważ każdy dokument w drzewie może wymagać zmiany, aby upewnić się, że „w lewo” i „w prawo” nadal mają sens, gdy coś zmieni się w hierarchii
- Zalety :
Pięć podejść omówiono bardziej szczegółowo w dokumentacji MongoDB .
Twój drugi pomysł łączy w sobie omówione powyżej podejścia „Odniesienia nadrzędne” i „Odniesienia do dzieci”. Takie podejście ułatwia znajdowanie zarówno dzieci, jak i rodzica oraz ułatwia aktualizowanie relacji i głównych danych artykułu (chociaż musisz zaktualizować zarówno pola nadrzędne, jak i podrzędne), ale nadal musisz przez nie przejść znaleźć przodków i potomków.
Jeśli interesuje Cię znajdowanie przodków i potomków (i zależy Ci na tym bardziej niż możliwości łatwej aktualizacji relacji), możesz rozważyć dodanie tablicy przodków do drugiego pomysłu, aby ułatwić wyszukiwanie przodków i potomków. Oczywiście aktualizowanie relacji staje się prawdziwym bólem, jeśli to zrobisz.
Wniosek:
-
Ostatecznie wszystko zależy od tego, jakie działania są najbardziej potrzebne. Ponieważ pracujesz z artykułami, których dane źródłowe (takie jak tytuł) mogą się często zmieniać, możesz uniknąć pierwszego pomysłu, ponieważ musisz zaktualizować nie tylko główny dokument tego artykułu, ale wszystkie dokumenty podrzędne, a także rodzic.
-
Twój drugi pomysł ułatwia odzyskanie bezpośredniego rodzica i dzieci. Aktualizacja relacji również nie jest zbyt trudna (z pewnością jest lepsza niż niektóre inne dostępne opcje).
-
Jeśli naprawdę chcesz ułatwić znajdowanie przodków i potomków kosztem równie łatwego aktualizowania relacji, wybierz dołączenie tablicy odniesień do przodków.
-
Ogólnie rzecz biorąc, staraj się zminimalizować liczbę wymaganych przemierzeń, ponieważ wymagają one uruchomienia pewnego rodzaju iteracji lub rekurencji, aby uzyskać żądane dane. Jeśli cenisz sobie możliwość aktualizowania relacji, powinieneś również wybrać opcję, która zmienia mniej węzłów w drzewie (referencje rodzicielskie, referencje podrzędne, a twój drugi pomysł może to zrobić).