Ich versuche, das Äquivalent von Fremdschlüsseln und Indizes in NoSQL KVP- oder Dokumentdatenbanken herauszufinden. Da es keine zentralen Tabellen gibt (um Schlüssel hinzuzufügen, die eine Beziehung zwischen zwei Objekten markieren), bin ich wirklich ratlos darüber, wie Sie Daten auf eine Weise abrufen können, die für normale Webseiten nützlich wäre.
Angenommen, ich habe einen Benutzer, und dieser Benutzer hinterlässt auf der gesamten Website viele Kommentare. Der einzige Weg, den ich mir vorstellen kann, um die Kommentare dieser Benutzer zu verfolgen, ist:
- Betten Sie sie in das Benutzerobjekt ein (was ziemlich nutzlos erscheint).
- Erstellen und pflegen Sie einen
user_id:comments
Wert, der eine Liste der Schlüssel jedes Kommentars enthält [Kommentar: 34, Kommentar: 197 usw.], damit ich sie nach Bedarf abrufen kann.
Wenn Sie jedoch das zweite Beispiel nehmen, werden Sie bald auf eine Mauer stoßen, wenn Sie sie zum Verfolgen anderer Dinge wie eines Schlüssels namens "active_comments" verwenden, der möglicherweise 30 Millionen IDs enthält, was es eine TON kostet , jede Seite abzufragen, nur um einige aktuelle zu kennen aktive Kommentare. Es wäre auch sehr anfällig für Rennbedingungen, da viele Seiten versuchen könnten, es gleichzeitig zu aktualisieren.
Wie kann ich Beziehungen wie die folgenden in einer NoSQL-Datenbank verfolgen?
- Alle Kommentare eines Benutzers
- Alle aktiven Kommentare
- Alle mit [Stichwort] getaggten Beiträge
- Alle Studenten in einem Club - oder alle Clubs, in denen ein Student ist
Oder denke ich falsch darüber nach?
quelle
Antworten:
Alle Antworten zum Speichern von Viele-zu-Viele-Assoziationen auf "NoSQL-Weise" beschränken sich auf dasselbe: das redundante Speichern von Daten.
In NoSQL entwerfen Sie Ihre Datenbank nicht basierend auf den Beziehungen zwischen Datenentitäten. Sie entwerfen Ihre Datenbank basierend auf den Abfragen, die Sie für sie ausführen. Verwenden Sie dieselben Kriterien, die Sie zum Denormalisieren einer relationalen Datenbank verwenden würden: Wenn es wichtiger ist, dass Daten zusammenhalten (denken Sie an Werte in einer durch Kommas getrennten Liste anstelle einer normalisierten Tabelle), tun Sie dies auf diese Weise.
Dies wird jedoch zwangsläufig für einen Abfragetyp (z. B. Kommentare eines Benutzers für einen bestimmten Artikel) auf Kosten anderer Abfragetypen (Kommentare für einen Artikel eines bestimmten Benutzers) optimiert. Wenn für Ihre Anwendung beide Abfragetypen gleichermaßen optimiert werden müssen, sollten Sie nicht denormalisieren. Ebenso sollten Sie keine NoSQL-Lösung verwenden, wenn Sie die Daten relational verwenden müssen.
Bei Denormalisierung und Redundanz besteht das Risiko, dass redundante Datensätze nicht mehr miteinander synchronisiert werden. Dies wird als Anomalie bezeichnet . Wenn Sie eine normalisierte relationale Datenbank verwenden, kann das RDBMS Anomalien verhindern. In einer denormalisierten Datenbank oder in NoSQL liegt es in Ihrer Verantwortung, Anwendungscode zu schreiben, um Anomalien zu vermeiden.
Man könnte meinen, dass es für eine NoSQL-Datenbank großartig wäre, die harte Arbeit zu leisten, um Anomalien für Sie zu verhindern. Es gibt ein Paradigma, das dies kann - das relationale Paradigma.
quelle
Der CouchDB-Ansatz schlägt vor, in der Kartenphase die richtigen Klassen von Dingen auszugeben und diese in "Reduzieren" zusammenzufassen. Sie können also alle Kommentare zuordnen und
1
für den angegebenen Benutzer ausgeben und später nur diejenigen ausdrucken. Es würde jedoch viel Festplattenspeicher erfordern, um dauerhafte Ansichten aller verfolgbaren Daten in couchDB zu erstellen. Übrigens haben sie auch diese Wiki-Seite über Beziehungen: http://wiki.apache.org/couchdb/EntityRelationship .Riak hingegen hat ein Werkzeug, um Beziehungen aufzubauen. Es ist Link. Sie können die Adresse eines verknüpften Dokuments (hier Kommentar) in das Stammdokument (hier Benutzerdokument) eingeben. Es hat einen Trick. Wenn es verteilt wird, kann es an vielen Orten gleichzeitig geändert werden. Es wird Konflikte verursachen und infolgedessen einen riesigen Vektoruhrbaum: / ..nicht so schlecht, nicht so gut.
Riak hat noch einen weiteren "Mechanismus". Es verfügt über einen zweischichtigen Schlüsselnamenraum, den sogenannten Bucket and Key. Beispiel: Wenn wir Club A, B und C und StudentX, StudentY haben, können Sie die folgende Konvention beibehalten:
und um die Beziehung zu lesen, listen Sie einfach die Schlüssel in bestimmten Eimern auf. Was stimmt damit nicht? Es ist verdammt langsam. Das Auflisten von Eimern hatte für riak nie Priorität. Es wird immer besser. Übrigens. Sie verschwenden keinen Speicher, da dieses Beispiel
{true}
mit einem einzelnen vollständigen Profil von StudentX oder Y verknüpft werden kann (hier sind Konflikte nicht möglich).Wie Sie es sehen NoSQL! = NoSQL. Sie müssen sich eine bestimmte Implementierung ansehen und diese selbst testen.
Erwähnt, bevor Column Stores gut für Beziehungen geeignet sind. Aber alles hängt von Ihren A- und C- und P-Anforderungen ab. Wenn Sie A nicht benötigen und weniger als Peta-Bytes haben, lassen Sie es einfach, fahren Sie mit MySql oder Postgres fort.
Viel Glück
quelle
user: userid: comment ist ein vernünftiger Ansatz - stellen Sie sich das als Äquivalent eines Spaltenindex in SQL vor, mit der zusätzlichen Anforderung, dass Sie nicht nach nicht indizierten Spalten abfragen können.
Hier müssen Sie über Ihre Anforderungen nachdenken. Eine Liste mit 30 Millionen Elementen ist nicht unangemessen, weil sie langsam ist, sondern weil es unpraktisch ist, jemals etwas damit zu tun. Wenn Ihre eigentliche Anforderung darin besteht, einige aktuelle Kommentare anzuzeigen, ist es besser, eine sehr kurze Liste zu führen, die aktualisiert wird, wenn ein Kommentar hinzugefügt wird. Denken Sie daran, dass für NoSQL keine Normalisierungsanforderungen bestehen. Rennbedingungen sind ein Problem mit Listen in einem grundlegenden Schlüsselwertspeicher, aber im Allgemeinen unterstützt Ihre Plattform Listen ordnungsgemäß, Sie können etwas mit Sperren tun oder Sie kümmern sich nicht wirklich um fehlgeschlagene Updates.
Wie bei Benutzerkommentaren - Erstellen Sie ein Index-Schlüsselwort: posts
Mehr vom Gleichen - wahrscheinlich eine Liste von Clubs als Eigentum von Studenten und ein Index auf diesem Feld, um alle Mitglieder eines Clubs zu erhalten
quelle
Du hast
Nun, in einer relationalen Datenbank wäre es normal, die Daten in einer Eins-zu-Viele-Beziehung zu normalisieren. Das ist das gleiche, was Sie auch in einer NoSQL-Datenbank tun würden. Indizieren Sie einfach die Felder, mit denen Sie die Informationen abrufen möchten.
Zum Beispiel sind die für Sie wichtigen Indizes
Wenn Sie NosDB (eine .NET-basierte NoSQL-Datenbank mit SQL-Unterstützung) verwenden, sind Ihre Abfragen wie folgt
Überprüfen Sie alle unterstützten Abfragetypen anhand ihres SQL-Spickzettel oder ihrer Dokumentation.
quelle