Jestem nowy w MongoDB - pochodzę z relacyjnej bazy danych. Chcę zaprojektować strukturę pytań z niektórymi komentarzami, ale nie wiem, jakiej relacji użyć w przypadku komentarzy: embed
lub reference
?
Pytanie z niektórymi komentarzami, takie jak stackoverflow , miałoby następującą strukturę:
Question
title = 'aaa'
content = bbb'
comments = ???
Najpierw chcę użyć osadzonych komentarzy (myślę, że embed
jest to zalecane w MongoDB), w następujący sposób:
Question
title = 'aaa'
content = 'bbb'
comments = [ { content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'} ]
To jasne, ale martwię się o tę sprawę: jeśli chcę edytować określony komentarz, w jaki sposób mogę uzyskać jego treść i pytanie? Nie ma nic, _id
co pozwoliłoby mi znaleźć, ani question_ref
pozwolić mi znaleźć jego pytanie. (Jestem tak początkujący, że nie wiem, czy można to zrobić bez _id
i question_ref
.)
Czy muszę używać ref
nie embed
? Więc muszę utworzyć nową kolekcję dla komentarzy?
Odpowiedzi:
To bardziej sztuka niż nauka. Mongo Dokumentacja schematów jest odniesienie dobra, ale jest kilka rzeczy do rozważenia:
Wrzuć jak najwięcej
Radość z bazy dokumentów polega na tym, że eliminuje ona wiele połączeń. Twoim pierwszym instynktem powinno być umieszczenie jak największej ilości w jednym dokumencie. Ponieważ dokumenty MongoDB mają strukturę i ponieważ możesz efektywnie wyszukiwać w obrębie tej struktury (oznacza to, że możesz wziąć część dokumentu, której potrzebujesz, więc rozmiar dokumentu nie powinien cię bardzo martwić), nie ma natychmiastowej potrzeby normalizacji danych, takich jak zrobiłbyś w SQL. W szczególności wszelkie dane, które nie są przydatne poza dokumentem nadrzędnym, powinny stanowić część tego samego dokumentu.
Oddzielne dane, do których można odwoływać się z wielu miejsc, do własnej kolekcji.
To nie tyle problem „przestrzeni dyskowej”, ile problem „spójności danych”. Jeśli wiele rekordów odnosi się do tych samych danych, bardziej wydajna i mniej podatna na błędy jest aktualizacja jednego rekordu i przechowywanie odniesień do niego w innych miejscach.
Uwagi dotyczące rozmiaru dokumentu
MongoDB nakłada limit rozmiaru 4 MB (16 MB z 1.8) na pojedynczy dokument. W świecie GB danych brzmi to niewielko, ale jest to również 30 tysięcy tweetów lub 250 typowych odpowiedzi na przepełnienie stosu lub 20 migotliwych zdjęć. Z drugiej strony jest to o wiele więcej informacji, niż można by jednorazowo przedstawić na typowej stronie internetowej. Najpierw zastanów się, co ułatwi twoje zapytania. W wielu przypadkach obawy dotyczące rozmiarów dokumentów będą przedwczesną optymalizacją.
Złożone struktury danych:
MongoDB może przechowywać dowolne głęboko zagnieżdżone struktury danych, ale nie może ich skutecznie wyszukiwać. Jeśli Twoje dane tworzą drzewo, las lub wykres, musisz skutecznie przechowywać każdy węzeł i jego krawędzie w osobnym dokumencie. (Należy pamiętać, że istnieją magazyny danych zaprojektowane specjalnie dla tego typu danych, które również należy wziąć pod uwagę)
Wskazano również , że nie można zwrócić podzbioru elementów w dokumencie. Jeśli musisz wybrać i wybrać kilka bitów każdego dokumentu, łatwiej będzie je rozdzielić.
Spójność danych
MongoDB stanowi kompromis między wydajnością a konsekwencją. Zasadą jest, że zmiany w jednym dokumencie są zawsze atomowe, a aktualizacji wielu dokumentów nigdy nie należy zakładać, że są atomowe. Nie ma także sposobu na „zablokowanie” rekordu na serwerze (można go wbudować w logikę klienta, używając na przykład pola „zablokuj”). Projektując schemat, zastanów się, jak zachować spójność danych. Zasadniczo im więcej trzymasz w dokumencie, tym lepiej.
Dla tego, co opisujesz, chciałbym osadzić komentarze i nadać każdemu komentarzowi pole identyfikatora o identyfikatorze obiektu. ObjectID ma osadzony znacznik czasu, więc możesz go użyć zamiast go utworzyć, jeśli chcesz.
źródło
Zasadniczo osadzanie jest dobre, jeśli masz relacje jeden-do-jednego lub jeden-do-wielu między jednostkami, a odniesienie jest dobre, jeśli masz relacje wiele-do-wielu.
źródło
Można wyszukać przez sub-dokumentu:
db.question.find({'comments.content' : 'xxx'})
.Spowoduje to zwrócenie całego dokumentu pytania. Aby edytować określony komentarz, musisz znaleźć komentarz na kliencie, dokonać edycji i zapisać go z powrotem w bazie danych.
Ogólnie, jeśli twój dokument zawiera tablicę obiektów, przekonasz się, że te pod-obiekty będą musiały zostać zmodyfikowane po stronie klienta.
źródło
Cóż, jestem trochę spóźniony, ale nadal chciałbym podzielić się moim sposobem tworzenia schematu.
Mam schematy wszystkiego, co można opisać słowem, tak jak zrobiłbyś to w klasycznym OOP.
NA PRZYKŁAD
Każdy schemat można zapisać jako dokument lub dokument podrzędny, dlatego deklaruję to dla każdego schematu.
Dokument:
Poddokument:
źródło
Natknąłem się na tę małą prezentację podczas samodzielnego badania tego pytania. Byłem zaskoczony, jak dobrze zostało to ułożone, zarówno informacje, jak i prezentacja.
http://openmymind.net/Multiple-Collections-Versus-Embedded-Documents
Podsumował:
źródło
a lot
? 3? 10? 100? Co jestlarge
? 1kb? 1 MB? 3 pola? 20 pól? Co to jestsmaller
/fewer
?Wiem, że jest to dość stare, ale jeśli szukasz odpowiedzi na pytanie PO dotyczące zwrotu tylko określonego komentarza, możesz użyć operatora $ (zapytanie) w następujący sposób:
źródło
Tak, możemy użyć odwołania w dokumencie. Aby zapełnić inny dokument tak jak sql i joins. W mongo db nie mają złączeń do mapowania jednego do wielu dokumentów relacji. Zamiast tego możemy użyć wypełnienia, aby spełnić nasz scenariusz.
Populacja to proces automatycznego zastępowania określonych ścieżek w dokumencie dokumentem (dokumentami) z innych kolekcji. Możemy wypełnić jeden dokument, wiele dokumentów, zwykły obiekt, wiele zwykłych obiektów lub wszystkie obiekty zwrócone z zapytania. Spójrzmy na kilka przykładów.
Lepiej możesz uzyskać więcej informacji na stronie: http://mongoosejs.com/docs/populate.html
źródło
Właściwie jestem ciekawy, dlaczego nikt nie mówił o specyfikacjach UML. Ogólna zasada jest taka, że jeśli masz agregację, powinieneś użyć referencji. Ale jeśli jest to kompozycja, połączenie jest silniejsze i powinieneś używać osadzonych dokumentów.
I szybko zrozumiesz, dlaczego jest to logiczne. Jeśli obiekt może istnieć niezależnie od rodzica, będziesz chciał uzyskać do niego dostęp, nawet jeśli rodzic nie istnieje. Ponieważ po prostu nie możesz osadzić go w nieistniejącym obiekcie nadrzędnym, musisz włączyć go do własnej struktury danych. A jeśli rodzic istnieje, po prostu połącz je ze sobą, dodając odwołanie do obiektu w rodzicu.
Naprawdę nie wiem, jaka jest różnica między tymi dwoma związkami? Oto link wyjaśniający je: Agregacja vs Kompozycja w UML
źródło
Stworzyłem ten quiz jako odniesienie, aby wiedzieć, czy powinieneś użyć jednego lub drugiego
http://indie-rok.github.io/embedded-vs-reference-mongo-db
źródło
Jeśli śledziłeś liczbę komentarzy i indeks komentarza, który chcesz zmienić, możesz użyć operatora kropki ( przykład SO ).
Mógłbyś zrobić np.
(jako inny sposób edycji komentarzy w pytaniu)
źródło