Alle Antworten (zum Zeitpunkt dieses Schreibens) setzen voraus, dass Redis, MongoDB und möglicherweise eine SQL-basierte relationale Datenbank im Wesentlichen dasselbe Tool sind: "Daten speichern". Sie berücksichtigen überhaupt keine Datenmodelle.
MongoDB: Komplexe Daten
MongoDB ist ein Dokumentenspeicher. So vergleichen Sie mit einer SQL-gesteuerten relationalen Datenbank: Relationale Datenbanken vereinfachen die Indizierung von CSV-Dateien, wobei jede Datei eine Tabelle ist. Dokumentenspeicher vereinfachen die Indizierung von JSON-Dateien, wobei jede Datei ein Dokument ist und mehrere Dateien zusammengefasst sind.
JSON-Dateien haben eine ähnliche Struktur wie XML- und YAML-Dateien sowie Wörterbücher wie Python. Denken Sie also an Ihre Daten in dieser Art von Hierarchie. Bei der Indizierung ist die Struktur der Schlüssel: Ein Dokument enthält benannte Schlüssel, die entweder weitere Dokumente, Arrays oder Skalarwerte enthalten. Betrachten Sie das folgende Dokument.
{
_id: 0x194f38dc491a,
Name: "John Smith",
PhoneNumber:
Home: "555 999-1234",
Work: "555 999-9876",
Mobile: "555 634-5789"
Accounts:
- "379-1111"
- "379-2574"
- "414-6731"
}
Das obige Dokument hat einen Schlüssel PhoneNumber.Mobile
, der Wert hat 555 634-5789
. Sie können eine Sammlung von Dokumenten durchsuchen, in denen der Schlüssel PhoneNumber.Mobile
einen Wert hat. Sie sind indiziert.
Es hat auch ein Array, Accounts
das mehrere Indizes enthält. Es ist möglich , dass ein Dokument abfragen , wo Accounts
enthält genau Werte eine Teilmenge, alle von einem gewissen Teilmenge von Werten, oder jede einiger Teilmenge von Werten. Das heißt, Sie können Accounts = ["379-1111", "379-2574"]
das oben Gesagte suchen und nicht finden. Sie können Accounts includes ["379-1111"]
das obige Dokument suchen und finden. und Sie können Accounts includes any of ["974-3785","414-6731"]
das oben genannte und jedes Dokument suchen und finden, das das Konto "974-3785" enthält, falls vorhanden.
Dokumente gehen so tief wie Sie wollen. PhoneNumber.Mobile
könnte ein Array oder sogar ein Unterdokument ( PhoneNumber.Mobile.Work
und PhoneNumber.Mobile.Personal
) enthalten. Wenn Ihre Daten stark strukturiert sind, sind Dokumente ein großer Fortschritt gegenüber relationalen Datenbanken.
Wenn Ihre Daten größtenteils flach, relational und starr strukturiert sind, ist eine relationale Datenbank besser geeignet. Auch hier ist das große Zeichen, ob Ihre Datenmodelle am besten für eine Sammlung miteinander verbundener CSV-Dateien oder eine Sammlung von XML / JSON / YAML-Dateien geeignet sind.
Bei den meisten Projekten müssen Sie Kompromisse eingehen und in einigen kleinen Bereichen, in denen entweder SQL- oder Dokumentenspeicher nicht passen, eine geringfügige Umgehung akzeptieren. Bei einigen großen, komplexen Projekten, in denen eine breite Datenverteilung gespeichert ist (viele Spalten; Zeilen sind irrelevant), ist es sinnvoll, einige Daten in einem Modell und andere Daten in einem anderen Modell zu speichern. Facebook verwendet sowohl SQL als auch eine Diagrammdatenbank (in der Daten in Knoten gespeichert und Knoten mit anderen Knoten verbunden werden). Craigslist verwendete früher MySQL und MongoDB, hatte jedoch versucht, sich vollständig auf MongoDB zu konzentrieren. Dies sind Orte, an denen die Spanne und die Beziehung der Daten erhebliche Nachteile aufweisen, wenn sie unter einem Modell zusammengefasst werden.
Redis: Schlüsselwert
Redis ist im Grunde ein Schlüsselwertspeicher. Mit Redis können Sie ihm einen Schlüssel geben und einen einzelnen Wert nachschlagen. Redis selbst kann Zeichenfolgen, Listen, Hashes und einige andere Dinge speichern. Es wird jedoch nur beim Namen nachgeschlagen.
Die Ungültigmachung des Caches ist eines der größten Probleme der Informatik. der andere benennt Dinge. Das bedeutet, dass Sie Redis verwenden, wenn Sie Hunderte von übermäßigen Suchvorgängen in einem Back-End vermeiden möchten, aber Sie müssen herausfinden, wann Sie einen neuen Suchvorgang benötigen.
Der offensichtlichste Fall einer Ungültigmachung ist die Aktualisierung beim Schreiben: Wenn Sie lesen user:Simon:lingots = NOTFOUND
, können Sie SELECT Lingots FROM Store s INNER JOIN UserProfile u ON s.UserID = u.UserID WHERE u.Username = Simon
das Ergebnis 100
als speichern SET user:Simon:lingots = 100
. Dann , wenn Sie Simon 5 lingots vergeben, lesen Sie user:Simon:lingots = 100
, SET user:Simon:lingots = 105
und UPDATE Store s INNER JOIN UserProfile u ON s.UserID = u.UserID SET s.Lingots = 105 WHERE u.Username = Simon
. Jetzt haben Sie 105 in Ihrer Datenbank und in Redis und können user:Simon:lingots
ohne Abfrage der Datenbank erhalten.
Der zweite Fall ist die Aktualisierung abhängiger Informationen. Angenommen, Sie generieren Teile einer Seite und speichern deren Ausgabe zwischen. Der Header zeigt die Erfahrung, das Level und den Geldbetrag des Spielers. Die Profilseite des Spielers enthält einen Block, in dem die Statistiken angezeigt werden. und so weiter. Der Spieler sammelt etwas Erfahrung. Nun, jetzt haben Sie mehrere templates:Header:Simon
, templates:StatsBox:Simon
, templates:GrowthGraph:Simon
und so weiter Bereiche , in denen Sie die Ausgabe von einer halben Dutzend Datenbankabfragen durch einen Template - Engine ausgeführt wird zwischengespeichert haben. Wenn Sie diese Seiten anzeigen, sagen Sie normalerweise:
$t = GetStringFromRedis("templates:StatsBox:" + $playerName);
if ($t == null) {
$t = BuildTemplate("StatsBox.tmpl",
GetStatsFromDatabase($playerName));
SetStringInRedis("Templates:StatsBox:" + $playerName, $t);
}
print $t;
Da Sie gerade die Ergebnisse von aktualisiert GetStatsFromDatabase("Simon")
haben, müssen Sie templates:*:Simon
Ihren Schlüsselwert-Cache verlassen. Wenn Sie versuchen, eine dieser Vorlagen zu rendern, wird Ihre Anwendung Daten aus Ihrer Datenbank (PostgreSQL, MongoDB) abrufen und in Ihre Vorlage einfügen. Dann speichert es das Ergebnis in Redis und macht hoffentlich keine Datenbankabfragen und Rendering-Vorlagen, wenn es das nächste Mal diesen Ausgabeblock anzeigt.
Mit Redis können Sie auch Nachrichtenwarteschlangen für Publisher und Abonnenten erstellen. Das ist ein ganz anderes Thema. Hier geht es darum, dass Redis ein Schlüsselwert-Cache ist, der sich von einer relationalen Datenbank oder einem Dokumentenspeicher unterscheidet.
Fazit
Wählen Sie Ihre Werkzeuge nach Ihren Bedürfnissen aus. Der größte Bedarf besteht normalerweise im Datenmodell, da dies bestimmt, wie komplex und fehleranfällig Ihr Code ist. Spezialisierte Anwendungen stützen sich auf die Leistung, Orte, an denen Sie alles in einer Mischung aus C und Assembly schreiben. Die meisten Anwendungen behandeln nur den allgemeinen Fall und verwenden ein Caching-System wie Redis oder Memcached, das viel schneller ist als eine Hochleistungs-SQL-Datenbank oder ein Dokumentenspeicher.