Wie würden Sie eine Viele-zu-Viele-Verbindung mit MongoDB herstellen?
Beispielsweise; Angenommen, Sie haben eine Benutzertabelle und eine Rollentabelle. Benutzer haben viele Rollen und Rollen haben viele Benutzer. In SQL Land würden Sie eine UserRoles-Tabelle erstellen.
Users:
Id
Name
Roles:
Id
Name
UserRoles:
UserId
RoleId
Wie wird dieselbe Art von Beziehung in MongoDB behandelt?
many-to-many
associations
mongodb
Josh Close
quelle
quelle
Antworten:
Abhängig von Ihren Abfrageanforderungen können Sie alles in das Benutzerdokument einfügen:
Um alle Ingenieure zu erhalten, verwenden Sie:
Wenn Sie die Rollen in separaten Dokumenten verwalten möchten, können Sie die _id des Dokuments anstelle des Namens in das Rollenarray aufnehmen:
und richten Sie die Rollen wie folgt ein:
quelle
Anstatt zu versuchen, nach unserer jahrelangen Erfahrung mit RDBMS zu modellieren, habe ich es viel einfacher gefunden, Dokument-Repository-Lösungen mit MongoDB, Redis und anderen NoSQL-Datenspeichern zu modellieren, indem ich sie für die Lese-Anwendungsfälle optimiere und dabei die atomaren Aspekte berücksichtige Schreibvorgänge, die von den Schreibanwendungsfällen unterstützt werden müssen.
Beispielsweise folgen die Verwendungen einer Domäne "Benutzer in Rollen":
Dies kann als die folgenden Dokumentvorlagen modelliert werden:
Um die Hochfrequenzverwendungen zu unterstützen, z. B. rollenbezogene Funktionen der Benutzerentität, wird User.Roles absichtlich denormalisiert, auf dem Benutzer gespeichert und Role.Users mit doppeltem Speicher.
Wenn dies im Text nicht ohne weiteres ersichtlich ist, ist dies jedoch die Art des Denkens, die bei der Verwendung von Dokumentrepositorys empfohlen wird.
Ich hoffe, dass dies dazu beiträgt, die Lücke in Bezug auf die Leseseite der Operationen zu schließen.
Für die Schreibseite wird empfohlen, nach atomaren Schreibvorgängen zu modellieren. Wenn für die Dokumentstrukturen beispielsweise eine Sperre erworben, ein Dokument, ein anderes und möglicherweise mehrere Dokumente aktualisiert und die Sperre aufgehoben werden muss, ist das Modell wahrscheinlich fehlgeschlagen. Nur weil wir verteilte Sperren erstellen können, heißt das nicht, dass wir sie verwenden sollen.
Für den Fall des Benutzers in Rollen-Modells fügen die Operationen, die unsere atomare Schreibvermeidung von Sperren erweitern, einen Benutzer zu einer Rolle hinzu oder entfernen ihn. In beiden Fällen führt ein erfolgreicher Vorgang dazu, dass sowohl ein einzelner Benutzer als auch ein einzelnes Rollendokument aktualisiert werden. Wenn etwas fehlschlägt, ist es einfach, eine Bereinigung durchzuführen. Dies ist der einzige Grund, warum das Muster "Arbeitseinheit" häufig verwendet wird, wenn Dokumentrepositorys verwendet werden.
Die Operation, die unsere atomare Schreibvermeidung von Sperren wirklich erweitert, löscht eine Rolle, was zu vielen Benutzeraktualisierungen führen würde, um den Role.name aus dem User.roles-Array zu entfernen. Diese Operation von clear wird dann im Allgemeinen nicht empfohlen, kann jedoch bei Bedarf durch Anordnen der Operationen implementiert werden:
Im Fall eines Problems, das am wahrscheinlichsten in Schritt 2 auftritt, ist ein Rollback einfach, da derselbe Satz von Benutzernamen aus Schritt 1 zum Wiederherstellen oder Fortfahren verwendet werden kann.
quelle
Ich bin gerade auf diese Frage gestoßen, und obwohl es eine alte ist, dachte ich, es wäre nützlich, ein paar Möglichkeiten hinzuzufügen, die in den gegebenen Antworten nicht erwähnt werden. Außerdem haben sich die Dinge in den letzten Jahren etwas weiterentwickelt, sodass hervorzuheben ist, dass SQL und NoSQL näher zusammenrücken.
Einer der Kommentatoren brachte die kluge warnende Haltung vor, dass „wenn Daten relational sind, verwenden Sie relational“. Dieser Kommentar ist jedoch nur in der relationalen Welt sinnvoll, in der Schemata immer vor der Anwendung stehen.
RELATIONAL WORLD: Strukturdaten> Anwendung schreiben, um sie zu erhalten
NOSQL WORLD: Designanwendung > Strukturdaten entsprechend
Auch wenn Daten relational sind, ist NoSQL immer noch eine Option. Zum Beispiel sind Eins-zu-Viele-Beziehungen überhaupt kein Problem und werden in MongoDB-Dokumenten ausführlich behandelt
Eine 2015 Lösung für ein 2010 Problem
Seit diese Frage gestellt wurde, gab es ernsthafte Versuche, noSQL näher an SQL heranzuführen. Das Team um Yannis Papakonstantinou von der University of California (San Diego) hat an FORWARD gearbeitet , einer Implementierung von SQL ++, die bald die Lösung für anhaltende Probleme wie das hier veröffentlichte sein könnte.
Auf einer praktischeren Ebene hat die Veröffentlichung von Couchbase 4.0 dazu geführt, dass Sie zum ersten Mal native JOINs in NoSQL ausführen können. Sie verwenden ihre eigene N1QL. Dies ist ein Beispiel
JOIN
aus ihren Tutorials :N1QL ermöglicht die meisten, wenn nicht alle SQL-Operationen, einschließlich Aggregration, Filterung usw.
DIE NICHT SO NEUE HYBRID-LÖSUNG
Wenn MongoDB immer noch die einzige Option ist, möchte ich auf meinen Punkt zurückkommen, dass die Anwendung Vorrang vor der Datenstruktur haben sollte. Keine der Antworten erwähnt die hybride Einbettung, wobei die meisten abgefragten Daten in das Dokument / Objekt eingebettet werden und Referenzen für eine Minderheit von Fällen aufbewahrt werden.
Beispiel: Können Informationen (außer Rollennamen) warten? Könnte das Bootstrapping der Anwendung schneller sein, wenn nichts angefordert wird, was der Benutzer noch nicht benötigt?
Dies kann der Fall sein, wenn sich der Benutzer anmeldet und alle Optionen für alle Rollen anzeigen muss, zu denen er gehört. Der Benutzer ist jedoch ein "Ingenieur", und Optionen für diese Rolle werden selten verwendet. Dies bedeutet, dass die Anwendung nur die Optionen für einen Ingenieur anzeigen muss, wenn er darauf klicken möchte.
Dies kann mit einem Dokument erreicht werden, das der Anwendung zu Beginn mitteilt (1), zu welchen Rollen der Benutzer gehört und (2) wo Informationen zu einem Ereignis abgerufen werden können, das mit einer bestimmten Rolle verknüpft ist.
Oder, noch besser, indizieren Sie das Feld role.name in der Rollensammlung, und Sie müssen möglicherweise auch ObjectID () nicht einbetten.
Ein weiteres Beispiel: Werden ständig Informationen zu ALLEN Rollen angefordert?
Es kann auch vorkommen, dass sich der Benutzer beim Dashboard anmeldet und in 90% der Fälle Aufgaben ausführt, die mit der Rolle "Ingenieur" verknüpft sind. Die hybride Einbettung könnte für diese bestimmte Rolle vollständig durchgeführt werden und Referenzen nur für den Rest behalten.
Schemalos zu sein ist nicht nur ein Merkmal von NoSQL, es könnte in diesem Fall von Vorteil sein. Es ist absolut gültig, verschiedene Objekttypen in der Eigenschaft "Rollen" eines Benutzerobjekts zu verschachteln.
quelle
Wenn Mitarbeiter und Unternehmen ein Entitätsobjekt sind, versuchen Sie, das folgende Schema zu verwenden:
quelle