Um eine Beziehung in MongoDB zu erstellen, betten Sie entweder ein BSON-Dokument in ein anderes ein oder referenzieren es von einem anderen.
MongoDB-Datenbanken funktionieren anders als relationale Datenbanken. Das gilt auch für Beziehungen.
In MongoDB können Sie eine Beziehung mit einer der beiden folgenden Methoden erstellen:
- Eingebettete Dokumente.
- Referenzierte Dokumente.
Die Methode, die Sie verwenden, hängt von den Daten ab und davon, wie Sie diese Daten abfragen möchten.
Eingebettete Beziehungen
Mit MongoDB können Sie Dokumente in Dokumente einbetten. Daher kann ein einzelnes Dokument seine eigenen Beziehungen enthalten.
Tatsächlich haben wir mit dieser Methode bereits eine Beziehung erstellt, als wir zum ersten Mal ein Dokument erstellt haben.
Eins-zu-Eins-Beziehung
Eine Eins-zu-Eins-Beziehung Hier hat das übergeordnete Dokument ein untergeordnetes Dokument und das untergeordnete Dokument ein übergeordnetes Dokument.
Beispielsweise könnte eine Geschäftsregel besagen, dass ein Künstler nur eine Adresse haben kann und dass die Adresse nur einem Künstler gehören kann.
Der folgende Code erstellt eine Eins-zu-Eins-Beziehung, die in das Dokument eingebettet ist.
db.artists.insert( { _id : 2, artistname : "Prince", address : { street : "Audubon Road", city : "Chanhassen", state : "Minnesota", country : "United States" } } )
Ergebnis:
WriteResult({ "nInserted" : 1 })
Eins-zu-Viele-Beziehung
Ein Eins-zu-Vielen Bei einer Beziehung kann das übergeordnete Dokument viele untergeordnete Dokumente haben, die untergeordneten Dokumente jedoch nur ein übergeordnetes Dokument.
Eine andere Geschäftsregel könnte also besagen, dass ein Künstler viele Alben haben kann, aber ein Album nur einem Künstler gehören kann.
Durch Ausführen des folgenden Codes wird eine Eins-zu-Viele-Beziehung erstellt:
db.artists.insert( { _id : 3, artistname : "Moby", albums : [ { album : "Play", year : 1999, genre : "Electronica" }, { album : "Long Ambients 1: Calm. Sleep.", year : 2016, genre : "Ambient" } ] } )
Ergebnis:
WriteResult({ "nInserted" : 1 })
Dokumentreferenzierte Beziehungen
Sie können eine Dokumentreferenz verwenden, um eine Beziehung herzustellen. Anstatt das untergeordnete Dokument in das übergeordnete Dokument einzubetten (wie wir es oben getan haben), trennen Sie das untergeordnete Dokument in ein eigenständiges Dokument.
Wir könnten also Folgendes tun:
Übergeordnetes Dokument
db.artists.insert( { _id : 4, artistname : "Rush" } )
Untergeordnete Dokumente
Wir fügen drei untergeordnete Dokumente ein – eines für jedes Bandmitglied:
db.musicians.insert( { _id : 9, name : "Geddy Lee", instrument : [ "Bass", "Vocals", "Keyboards" ], artist_id : 4 } )
db.musicians.insert( { _id : 10, name : "Alex Lifeson", instrument : [ "Guitar", "Backing Vocals" ], artist_id : 4 } )
db.musicians.insert( { _id : 11, name : "Neil Peart", instrument : "Drums", artist_id : 4 } )
Abfrage der Beziehung
Nachdem Sie die beiden obigen Dokumente eingefügt haben, können Sie $lookup
verwenden um einen Left Outer Join für die beiden Sammlungen auszuführen.
Dies in Verbindung mit aggregate()
-Methode und $match
um den bestimmten Künstler anzugeben, an dem Sie interessiert sind, werden übergeordnete und untergeordnete Dokumente in einem zurückgegeben.
db.artists.aggregate([ { $lookup: { from: "musicians", localField: "_id", foreignField: "artist_id", as: "band_members" } }, { $match : { artistname : "Rush" } } ]).pretty()
Ergebnis:
{ "_id" : 4, "artistname" : "Rush", "band_members" : [ { "_id" : 9, "name" : "Geddy Lee", "instrument" : [ "Bass", "Vocals", "Keyboards" ], "artist_id" : 4 }, { "_id" : 10, "name" : "Alex Lifeson", "instrument" : [ "Guitar", "Backing Vocals" ], "artist_id" : 4 }, { "_id" : 11, "name" : "Neil Peart", "instrument" : "Drums", "artist_id" : 4 } ] }
Wie Sie sehen, stammen die ersten beiden Felder aus der Künstlersammlung und der Rest aus der Musikersammlung.
Wenn Sie also nur die Künstlersammlung selbst abfragen:
db.artists.find( { artistname : "Rush" } )
Sie würden nur Folgendes erhalten:
{ "_id" : 4, "artistname" : "Rush" }
Es werden keine zugehörigen Daten zurückgegeben.
Wann sollten eingebettete Dokumente im Vergleich zu referenzierten Dokumenten verwendet werden
Beide Methoden der Beziehungsgestaltung haben ihre Vor- und Nachteile. Es gibt Zeiten, in denen Sie möglicherweise eingebettete Dokumente verwenden, und manchmal verwenden Sie referenzierte Dokumente.
Wann sollten eingebettete Beziehungen verwendet werden
Einer der Hauptvorteile der eingebetteten Beziehungsmethode ist die Leistung. Wenn die Beziehung in das Dokument eingebettet ist, werden Abfragen schneller ausgeführt, als wenn sie über mehrere Dokumente verteilt wären. MongoDB muss nur das eine Dokument zurückgeben, anstatt mehrere Dokumente zusammenzuführen, um die Beziehungen abzurufen. Dies kann zu einer erheblichen Leistungssteigerung führen – insbesondere bei der Arbeit mit vielen Daten.
Eingebettete Beziehungen erleichtern auch das Schreiben von Abfragen. Anstatt komplexe Abfragen zu schreiben, die viele Dokumente über ihre eindeutige Kennung verbinden, können Sie alle zugehörigen Daten in einer einzigen Abfrage zurückgeben.
Eine weitere zu beachtende Überlegung ist, dass MongoDB die Atomarität nur auf Dokumentebene sicherstellen kann. Dokumentaktualisierungen für ein einzelnes Dokument sind immer atomar, aber nicht für mehrere Dokumente.
Wenn mehrere Benutzer auf die Daten zugreifen, besteht immer die Möglichkeit, dass zwei oder mehr Benutzer versuchen, dasselbe Dokument mit unterschiedlichen Daten zu aktualisieren. In diesem Fall stellt MongoDB sicher, dass kein Konflikt auftritt und jeweils nur ein Datensatz aktualisiert wird. MongoDB kann dies nicht über mehrere Dokumente hinweg gewährleisten.
Im Allgemeinen können eingebettete Beziehungen in den meisten Fällen verwendet werden, solange das Dokument innerhalb der Größenbeschränkung (16 Megabyte zum Zeitpunkt des Schreibens) und/oder seiner Verschachtelungsbeschränkung (100 Ebenen tief zum Zeitpunkt des Schreibens) bleibt.
Eingebettete Beziehungen sind jedoch nicht für alle geeignet Gelegenheiten. Es kann Situationen geben, in denen es sinnvoller ist, eine dokumentreferenzierte Beziehung zu erstellen.
Wann werden referenzierte Beziehungen verwendet?
Für Daten, die in vielen Dokumenten wiederholt werden müssen, kann es hilfreich sein, sie in einem eigenen separaten Dokument zu haben. Dies kann Fehler reduzieren und dabei helfen, die Daten konsistent zu halten (wobei zu berücksichtigen ist, dass Aktualisierungen mehrerer Dokumente nicht atomar sind).
Im obigen Beispiel könnte ein Musiker Mitglied (oder Ex-Mitglied) vieler Bands sein. Einige könnten auch Alben für andere Künstler produzieren, Studenten unterrichten, Kliniken betreiben usw. Außerdem könnten viele Daten zu jedem Musiker gespeichert werden. Daher ist es in diesem Fall sinnvoll, für jeden Musiker ein separates Dokument zu haben.
Wenn Sie außerdem glauben, dass Ihre eingebetteten Dokumente die von MongoDB auferlegte Dateigrößenbeschränkung überschreiten könnten, müssen Sie einige Daten in separaten Dokumenten speichern.