Ich bin neu in diesem ganzen NOSQL-Zeug und war kürzlich fasziniert von mongoDB. Ich erstelle eine neue Website von Grund auf neu und habe mich für MONGODB / NORM (für C #) als meine einzige Datenbank entschieden. Ich habe viel darüber gelesen, wie Sie Ihre Dokumentmodelldatenbank richtig gestalten können, und ich denke, dass mein Entwurf größtenteils ziemlich gut funktioniert hat. Ich bin ungefähr 6 Monate in meiner neuen Site und sehe allmählich Probleme mit der Vervielfältigung / Synchronisierung von Daten, mit denen ich mich immer wieder befassen muss. Nach dem, was ich gelesen habe, wird dies im Dokumentmodell erwartet, und für die Leistung ist es sinnvoll. IE Sie kleben eingebettete Objekte in Ihr Dokument, damit es schnell gelesen werden kann - keine Verknüpfungen; Aber natürlich kann man nicht immer einbetten, also hat Mongodb dieses Konzept einer DbReference, das im Grunde analog zu einem Fremdschlüssel in relationalen DBs ist.
Hier ist ein Beispiel: Ich habe Benutzer und Ereignisse; Beide erhalten ihr eigenes Dokument. Benutzer nehmen an Veranstaltungen teil. Bei Veranstaltungen haben Benutzer Teilnehmer. Ich habe beschlossen, eine Liste von Ereignissen mit begrenzten Daten in die Benutzerobjekte einzubetten. Ich habe eine Liste von Benutzern auch als "Teilnehmer" in die Ereignisobjekte eingebettet. Das Problem hier ist jetzt, dass ich die Benutzer mit der Liste der Benutzer synchron halten muss, die auch in das Ereignisobjekt eingebettet ist. Während ich es lese, scheint dies der bevorzugte Ansatz und die NOSQL-Methode zu sein. Das Abrufen ist schnell, aber der Fallback ist, wenn ich das Hauptbenutzerdokument aktualisiere. Ich muss auch in die Ereignisobjekte gehen, möglicherweise alle Verweise auf diesen Benutzer finden und diese ebenfalls aktualisieren.
Die Frage, die ich habe, ist also, ob dies ein ziemlich häufiges Problem ist, mit dem sich die Leute befassen müssen. Wie viel muss dieses Problem passieren, bevor Sie sagen "Vielleicht passt die NOSQL-Strategie nicht zu dem, was ich hier versuche"? Wann wird der Leistungsvorteil, keine Verknüpfungen durchführen zu müssen, zu einem Nachteil, da es schwierig ist, Daten in eingebetteten Objekten synchron zu halten und dafür mehrere Lesevorgänge in der Datenbank durchzuführen?
quelle
Antworten:
Nun, das ist der Kompromiss mit Dokumentenspeichern. Sie können wie jedes Standard-RDMS normalisiert speichern und sollten sich so weit wie möglich um eine Normalisierung bemühen. Nur dort, wo die Leistung beeinträchtigt wird, sollten Sie die Normalisierung aufheben und Ihre Datenstrukturen reduzieren. Der Kompromiss ist die Leseeffizienz gegenüber den Aktualisierungskosten.
Mongo verfügt über wirklich effiziente Indizes, die die Normalisierung wie bei einem herkömmlichen RDMS vereinfachen können (die meisten Dokumentenspeicher bieten diese nicht kostenlos an, weshalb Mongo eher ein Hybrid als ein reiner Dokumentenspeicher ist). Auf diese Weise können Sie eine Beziehungssammlung zwischen Benutzern und Ereignissen erstellen. Es ist analog zu einer Ersatztabelle in einem tabellarischen Datenspeicher. Indizieren Sie die Ereignis- und Benutzerfelder, und es sollte ziemlich schnell gehen und Ihnen helfen, Ihre Daten besser zu normalisieren.
Ich möchte die Effizienz des Abflachens einer Struktur darstellen, anstatt sie normal zu halten, wenn es um die Zeit geht, die ich zum Aktualisieren von Datensatzdaten benötige, und das Auslesen der Anforderungen in einer Abfrage. Sie können es in Bezug auf die große O-Notation tun, aber Sie müssen nicht so schick sein. Schreiben Sie einfach einige Zahlen auf Papier, basierend auf einigen Anwendungsfällen mit unterschiedlichen Modellen für die Daten, und bekommen Sie ein gutes Gefühl dafür, wie viel Arbeit erforderlich ist.
Grundsätzlich versuche ich zunächst, die Wahrscheinlichkeit vorherzusagen, wie viele Aktualisierungen ein Datensatz haben wird und wie oft er gelesen wird. Dann versuche ich vorherzusagen, wie hoch die Kosten für ein Update im Vergleich zu einem Lesevorgang sind, wenn es sowohl normalisiert als auch abgeflacht ist (oder vielleicht eine teilweise Kombination der beiden, die ich mir vorstellen kann ... viele Optimierungsoptionen). Ich kann dann die Einsparungen bei der Aufbewahrung im Vergleich zu den Kosten für den Aufbau der Daten aus normalisierten Quellen beurteilen. Sobald ich alle Variablen geplottet habe und die Ersparnisse, sie flach zu halten, mir eine Menge sparen, werde ich sie flach halten.
Einige Tipps:
Es gibt viele andere Ideen, die Sie anwenden können. Es gibt viele großartige Online-Blogs, die wie highscalabilty.org darauf eingehen und sicherstellen, dass Sie den CAP-Satz verstehen.
Berücksichtigen Sie auch eine Caching-Ebene wie Redis oder Memcache. Ich werde eines dieser Produkte vor meine Datenschicht stellen. Wenn ich Mongo abfrage (das alles normalisiert speichert), verwende ich die Daten, um eine abgeflachte Darstellung zu erstellen und sie im Cache zu speichern. Wenn ich die Daten aktualisiere, mache ich alle Daten im Cache ungültig, die auf das verweisen, was ich aktualisiere. (Obwohl Sie sich die Zeit nehmen müssen, um Daten ungültig zu machen und Daten im Cache zu verfolgen, der unter Berücksichtigung Ihrer Skalierungsfaktoren aktualisiert wird). Jemand sagte einmal: "Die zwei schwierigsten Dinge in der Informatik sind das Benennen von Dingen und die Ungültigmachung des Caches."
Hoffentlich hilft das!
quelle
Versuchen Sie, Ihrem User-Objekt eine IList vom Typ UserEvent-Eigenschaft hinzuzufügen. Sie haben nicht viel darüber angegeben, wie Ihr Domain-Modell aufgebaut ist. Beispiele finden Sie in der NoRM-Gruppe http://groups.google.com/group/norm-mongodb/topics .
quelle