Alle Antworten (zum Zeitpunkt dieses Schreibens) gehen davon aus, dass Redis, MongoDB und vielleicht eine SQL-basierte relationale Datenbank im Wesentlichen das gleiche Tool sind: "Daten speichern". Sie berücksichtigen die Datenmodelle überhaupt nicht.
MongoDB: Komplexe Daten
MongoDB ist ein Dokumentenspeicher. Zum Vergleich mit einer SQL-gesteuerten relationalen Datenbank: relationale Datenbanken vereinfachen sich zu indizierten CSV-Dateien, wobei jede Datei eine Tabelle ist; Dokumentenspeicher vereinfachen sich zu indizierten JSON-Dateien, wobei jede Datei ein Dokument ist und mehrere Dateien gruppiert werden.
JSON-Dateien sind ähnlich strukturiert wie XML- und YAML-Dateien und wie Dictionaries in Python, so dass Sie Ihre Daten in dieser Art von Hierarchie betrachten können. Bei der Indizierung ist die Struktur der Schlüssel: Ein Dokument enthält benannte Schlüssel, die entweder weitere Dokumente, Arrays oder skalare Werte 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 oben genannte Dokument hat einen Schlüssel, PhoneNumber.Mobile
der einen Wert hat 555 634-5789
. Sie können eine Sammlung von Dokumenten durchsuchen, bei denen der Schlüssel, PhoneNumber.Mobile
hat einen gewissen Wert; sie sind indiziert.
Außerdem verfügt es über eine Reihe von Accounts
die mehrere Indizes enthalten. Es ist möglich, nach einem Dokument zu suchen, bei dem Accounts
enthält genau eine Teilmenge von Werten, alle einer Teilmenge von Werten, oder jede einer Teilmenge von Werten. Das heißt, Sie können suchen nach Accounts = ["379-1111", "379-2574"]
und die obigen Angaben nicht finden; Sie können suchen nach Accounts includes ["379-1111"]
und finden Sie das oben genannte Dokument; und Sie können suchen nach Accounts includes any of ["974-3785","414-6731"]
und suchen Sie das oben genannte Dokument und gegebenenfalls alle Dokumente, die das Konto "974-3785" enthalten.
Die Dokumente gehen so tief, wie Sie wollen. PhoneNumber.Mobile
könnte ein Array oder sogar ein Unterdokument enthalten ( PhoneNumber.Mobile.Work
y PhoneNumber.Mobile.Personal
). Wenn Ihre Daten stark strukturiert sind, stellen Dokumente einen großen Fortschritt gegenüber relationalen Datenbanken dar.
Wenn Ihre Daten größtenteils flach, relational und starr strukturiert sind, sind Sie mit einer relationalen Datenbank besser beraten. Auch hier kommt es darauf an, ob Ihre Datenmodelle am besten in einer Sammlung von miteinander verknüpften CSV-Dateien oder in einer Sammlung von XML/JSON/YAML-Dateien abgebildet werden.
Bei den meisten Projekten müssen Sie einen Kompromiss eingehen und in einigen kleinen Bereichen, in denen SQL oder Document Stores nicht passen, eine kleine Umgehung in Kauf nehmen. Bei einigen großen, komplexen Projekten, in denen eine große Bandbreite an Daten gespeichert wird (viele Spalten; Zeilen sind irrelevant), wird es sinnvoll sein, einige Daten in einem Modell und andere Daten in einem anderen Modell zu speichern. Facebook verwendet sowohl SQL als auch eine Graphdatenbank (bei der die Daten in Knoten gespeichert werden und die Knoten mit anderen Knoten verbunden sind); Craigslist verwendete früher MySQL und MongoDB, hat aber eine vollständige Umstellung auf MongoDB in Erwägung gezogen. Dies sind Orte, an denen der Umfang und die Beziehungen der Daten mit erheblichen Nachteilen verbunden sind, wenn sie in einem einzigen Modell zusammengefasst werden.
Redis: Schlüssel-Werte
Redis ist im Wesentlichen ein Key-Value-Speicher. In Redis können Sie einen Schlüssel angeben und einen einzelnen Wert nachschlagen. Redis selbst kann Zeichenketten, Listen, Hashes und ein paar andere Dinge speichern, sucht aber nur nach Namen.
Die Invalidierung des Cache ist eines der schwierigsten Probleme der Informatik; das andere ist die Benennung von Dingen. Das bedeutet, dass Sie Redis verwenden werden, wenn Sie Hunderte von überflüssigen Nachschlagevorgängen in einem Backend vermeiden wollen, aber Sie müssen herausfinden, wann Sie einen neuen Nachschlagevorgang benötigen.
Der offensichtlichste Fall einer Ungültigkeitserklärung ist die Aktualisierung beim Schreiben: Wenn Sie lesen user:Simon:lingots = NOTFOUND
könnten Sie SELECT Lingots FROM Store s INNER JOIN UserProfile u ON s.UserID = u.UserID WHERE u.Username = Simon
und speichern das Ergebnis, 100
als SET user:Simon:lingots = 100
. Wenn du Simon 5 Lingots zuteilst, liest du dann user:Simon:lingots = 100
, SET user:Simon:lingots = 105
y 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.
Der zweite Fall ist die Aktualisierung der abhängigen Informationen. Nehmen wir an, Sie generieren Teile einer Seite und speichern deren Ausgabe im Cache. Die Kopfzeile zeigt die Erfahrung, die Stufe und den Geldbetrag des Spielers an; die Profilseite des Spielers hat einen Block, der seine Statistiken anzeigt, und so weiter. Der Spieler gewinnt an Erfahrung. Nun, jetzt haben Sie mehrere templates:Header:Simon
, templates:StatsBox:Simon
, templates:GrowthGraph:Simon
und so weiter Felder, in denen Sie die Ausgabe eines halben Dutzend Datenbankabfragen, die über eine Template-Engine laufen, zwischengespeichert haben. Normalerweise, wenn Sie diese Seiten anzeigen, sagen Sie:
$t = GetStringFromRedis("templates:StatsBox:" + $playerName);
if ($t == null) {
$t = BuildTemplate("StatsBox.tmpl",
GetStatsFromDatabase($playerName));
SetStringInRedis("Templates:StatsBox:" + $playerName, $t);
}
print $t;
Denn Sie haben gerade die Ergebnisse von GetStatsFromDatabase("Simon")
müssen Sie die templates:*:Simon
aus Ihrem Key-Value-Cache. Wenn Sie versuchen, eine dieser Vorlagen zu rendern, holt Ihre Anwendung fleißig Daten aus Ihrer Datenbank (PostgreSQL, MongoDB) und fügt sie in Ihre Vorlage ein; dann speichert sie das Ergebnis in Redis und macht sich hoffentlich nicht die Mühe, Datenbankabfragen zu machen und Vorlagen zu rendern, wenn sie den Ausgabeblock das nächste Mal anzeigt.
Mit Redis können Sie auch Publisher-Subscribe-Nachrichtenwarteschlangen und dergleichen erstellen. Das ist ein ganz anderes Thema. Der Punkt hier ist, dass Redis ein Key-Value-Cache ist, der sich von einer relationalen Datenbank oder einem Dokumentenspeicher unterscheidet.
Schlussfolgerung
Wählen Sie Ihre Werkzeuge nach Ihren Bedürfnissen aus. Der größte Bedarf ist in der Regel das Datenmodell, da dieses bestimmt, wie komplex und fehleranfällig Ihr Code ist. Spezialisierte Anwendungen, bei denen Sie alles in einer Mischung aus C und Assembler schreiben, werden sich auf die Leistung stützen; die meisten Anwendungen werden nur den allgemeinen Fall behandeln und ein Caching-System wie Redis oder Memcached verwenden, das viel schneller ist als eine Hochleistungs-SQL-Datenbank oder ein Dokumentenspeicher.