Im vergangenen Jahr kann man in der Tech-Welt keinen RSS-Reader öffnen, ohne auf einen Artikel über NoSQL-Datenbanken zu stoßen. MongoDB, CouchDB, Cassandra, Redis — jede verspricht etwas anderes, aber alle teilen eine Idee: Das relationale Modell ist nicht der einzige Weg. Als Team, das das letzte Jahrzehnt mit Oracle und PostgreSQL gearbeitet hat, haben wir beschlossen zu untersuchen, ob NoSQL ein Hype oder ein echter Paradigmenwechsel ist.
Warum NoSQL-Datenbanken entstanden sind¶
Der Begriff NoSQL tauchte erstmals 2009 auf einer Konferenz in San Francisco auf, aber die Idee nicht-relationaler Speicherung ist viel älter. Der Hauptantrieb war einfach — Webanwendungen wie Facebook, Google und Amazon mussten solche Datenmengen und solche Anfragenzahlen verarbeiten, dass traditionelle relationale Datenbanken einfach nicht mithalten konnten. Oracle kann noch so leistungsfähig sein, aber wenn man horizontale Skalierung über Hunderte von Servern braucht, wird das relationale Modell mit seinen JOINs, Transaktionen und Normalisierung zum Engpass.
Google veröffentlichte das Bigtable-Paper 2006, Amazon stellte Dynamo 2007 vor und diese Arbeiten inspirierten eine ganze Generation von Open-Source-Datenbanken. Cassandra entstand bei Facebook, HBase implementiert das Bigtable-Modell auf Hadoop, MongoDB kam mit einem Dokumentenmodell, das für Webentwickler intuitiv ist. Jede dieser Datenbanken geht einen Kompromiss ein — sie tauscht etwas von den ACID-Eigenschaften gegen Skalierbarkeit, Flexibilität oder Performance ein.
MongoDBs Dokumentenmodell¶
MongoDB ist eine Dokumentendatenbank, was bedeutet, dass sie Daten als JSON-ähnliche Dokumente speichert (das interne Format ist BSON — Binary JSON). Jedes Dokument kann eine andere Struktur haben; es ist nicht nötig, vorab ein Schema zu definieren. Das ist ein fundamentaler Unterschied zu relationalen Datenbanken, bei denen man eine Tabelle mit festen Spalten erstellen muss, bevor man Daten einfügen kann.
Für Webentwickler ist dieses Modell natürlich. Wenn Ihre Anwendung mit JSON-Objekten arbeitet (und 2011 tut das fast jede Webanwendung), können Sie diese direkt in der Datenbank speichern, ohne sie auf ein relationales Schema abzubilden. Kein ORM, kein Impedance Mismatch. Ein Dokument in MongoDB kann verschachtelte Objekte und Arrays enthalten, was es ermöglicht, komplexe Datenstrukturen in einem einzigen Dokument statt in mehreren verknüpften Tabellen abzubilden.
Wann MongoDB Sinn macht¶
MongoDB glänzt in Situationen, in denen das Schema nicht im Voraus bekannt ist oder sich häufig ändert. Ein typisches Beispiel sind Katalogsysteme — jede Produktkategorie kann andere Attribute haben. In einer relationalen Datenbank würde man mit dem EAV-Pattern (Entity-Attribute-Value) arbeiten oder Dutzende von nullable-Spalten haben. In MongoDB hat jedes Produkt einfach genau die Attribute, die es braucht.
Ein weiterer großartiger Anwendungsfall ist Logging und Analytik. Logs haben eine variable Struktur und das Volumen wächst exponentiell. MongoDB bewältigt hohen Write-Throughput und bietet mit Capped Collections automatische Rotation alter Daten. Für die Aggregation über Logs verwenden wir MapReduce — nicht so bequem wie SQL GROUP BY, aber effizienter für große Datenmengen.
Content-Management-Systeme sind ein weiterer natürlicher Fit. Artikel, Seiten, Kommentare — jeder Inhaltstyp kann eine andere Struktur und verschachtelte Komponenten haben. MongoDB ermöglicht es, eine ganze Seite als einzelnes Dokument inklusive Metadaten, Tags und Kommentaren zu speichern. Das Lesen ist dann eine einzige Abfrage statt eines komplexen JOINs über fünf Tabellen.
Wann MongoDB KEINEN Sinn macht¶
Und nun der wichtige Teil — wann man NoSQL NICHT verwenden sollte. Wenn Ihre Daten starke relationale Verknüpfungen haben und Sie konsistente Transaktionen über mehrere Entitäten benötigen, ist eine relationale Datenbank nach wie vor die bessere Wahl. Ein Bankensystem, bei dem eine Überweisung atomar sein muss (von einem Konto abbuchen und auf ein anderes gutschreiben in einer einzigen Transaktion) — das können Sie mit MongoDB nicht zuverlässig machen. MongoDB hat keine Multi-Document-Transaktionen.
Reporting und Ad-hoc-Abfragen sind eine weitere Schwäche. SQL ist eine unglaublich ausdrucksstarke Sprache für Datenabfragen. Die MongoDB-Abfragesprache ist eingeschränkter — komplexe Aggregationen erfordern MapReduce, das langsam und schwer zu debuggen ist. Wenn Ihre Analysten täglich neue Abfragen über Daten schreiben müssen, wird Oracle mit SQL Developer immer noch produktiver sein als die MongoDB Shell.
Achten Sie auch auf Datenduplizierung. Im relationalen Modell ist die Adresse eines Kunden an einer Stelle und alle Bestellungen referenzieren sie. In MongoDB könnte man die Adresse in jede Bestellung einbetten — was schnell zum Lesen ist, aber wenn der Kunde seine Adresse ändert, müssen alle Dokumente aktualisiert werden. Das ist der grundlegende Kompromiss des Dokumentenmodells.
Skalierung — Sharding und Replica Sets¶
Einer der Hauptvorteile von MongoDB ist die native Unterstützung für horizontale Skalierung. Sharding verteilt Daten über mehrere Server nach einem Shard Key — zum Beispiel nach Kunden-ID. Jeder Shard enthält eine Teilmenge der Daten und der MongoDB-Router (mongos) leitet Abfragen automatisch an den richtigen Shard weiter. Das Hinzufügen eines neuen Shards ist relativ einfach und MongoDB rebalanciert die Daten automatisch.
Replica Sets sorgen für Hochverfügbarkeit. Jeder Shard hat einen primären Knoten und einen oder mehrere sekundäre Knoten, die Daten asynchron replizieren. Wenn der primäre Knoten ausfällt, wird automatisch ein sekundärer Knoten als neuer Primärer gewählt. Das ist deutlich einfacher als das Einrichten von Oracle RAC oder PostgreSQL Streaming Replication.
Aber Vorsicht — asynchrone Replikation bedeutet, dass man bei einem Failover Daten verlieren kann, die noch nicht repliziert wurden. MongoDB bietet Write-Concern-Einstellungen, mit denen man Bestätigungen von der Mehrheit der Knoten verlangen kann, aber das reduziert die Performance. Es ist immer ein Kompromiss zwischen Konsistenz und Performance.
Unsere Erfahrungen aus einem Pilotprojekt¶
Wir haben beschlossen, MongoDB in einem internen Projekt auszuprobieren — ein System zur Verwaltung der Konfiguration unserer Server. Jeder Server hat eine andere Kombination von Diensten, verschiedene Parameter und eine Änderungshistorie. Im relationalen Modell wären das fünf Tabellen mit vielen nullable-Spalten gewesen. In MongoDB ist jeder Server ein einzelnes Dokument mit genau den Attributen, die er braucht.
Der erste Eindruck war großartig — die Entwicklung ging schnell, wir mussten uns nicht mit Schema-Migrationen beschäftigen und die Abfragen waren intuitiv. Probleme kamen auf, als wir Server nach einer Kombination von Attributen suchen mussten — MongoDB erfordert Indizes auf jedem Feld, das man effizient durchsuchen will, und zusammengesetzte Indizes haben ihre Einschränkungen. Das zweite Problem war das Fehlen von JOINs — als wir Server mit Informationen über ihr Rechenzentrum anzeigen wollten, mussten wir zwei Abfragen machen und die Daten in der Anwendung zusammenführen.
Andererseits war das Hinzufügen eines neuen Attributs zur Serverkonfiguration trivial — kein ALTER TABLE, keine Migration, wir begannen einfach, das neue Attribut zu speichern. Für ein System, das sich schnell weiterentwickelt, ist diese Flexibilität unbezahlbar.
Vergleich von NoSQL-Datenbanken¶
MongoDB ist nicht die einzige NoSQL-Datenbank und jede hat ihre Nische. CouchDB ist ebenfalls eine Dokumentendatenbank, nutzt aber eine HTTP-API und hat eingebaute Konfliktlösung für Offline-first-Anwendungen. Cassandra ist eine spaltenorientierte Datenbank, optimiert für extrem hohen Write-Throughput — ideal für Logging und IoT-Daten. Redis ist ein In-Memory Key-Value Store, großartig für Cache und Session Management. HBase läuft auf Hadoop und ist für analytische Workloads über Petabytes von Daten konzipiert.
Die Wahl der richtigen Datenbank hängt von Ihrem Anwendungsfall ab. Es gibt keine universelle Antwort. Oft ist die beste Lösung Polyglot Persistence — mehrere Datenbanken in einer Anwendung zu verwenden, jede für das, was sie am besten kann. Relationale Datenbanken für Transaktionen, MongoDB für flexible Dokumente, Redis für Cache, Elasticsearch für Volltextsuche.
Das CAP-Theorem und die Realität¶
Wenn wir über NoSQL sprechen, müssen wir das CAP-Theorem erwähnen. Eric Brewer formulierte die Hypothese, dass ein verteiltes System maximal zwei von drei Eigenschaften erfüllen kann: Consistency (Konsistenz), Availability (Verfügbarkeit) und Partition Tolerance (Partitionstoleranz). In der Praxis bedeutet das: Bei einem Netzwerkproblem muss man sich entscheiden — entweder veraltete Daten zurückgeben (AP-System) oder nicht verfügbar sein, bis das Netzwerk wiederhergestellt ist (CP-System).
MongoDB ist ein CP-System — wenn der primäre Knoten nicht verfügbar ist, sind einige Daten vorübergehend unzugänglich, bis ein neuer Primärer gewählt ist. Cassandra ist ein AP-System — es antwortet immer, kann aber veraltete Daten zurückgeben. Traditionelle relationale Datenbanken auf einem einzelnen Server ignorieren die Partitionstoleranz einfach, weil sie keine Verteilung haben.
Fazit¶
NoSQL-Datenbanken sind kein Ersatz für relationale Datenbanken — sie sind eine Ergänzung. MongoDB ist eine großartige Wahl für flexible Schemas, hohen Write-Throughput und horizontale Skalierung. Aber für Transaktionen, komplexe Abfragen und stark relationale Daten bleiben wir bei PostgreSQL und Oracle. Die Zukunft liegt in Polyglot Persistence — die richtige Datenbank für das richtige Problem.
Brauchen Sie Hilfe bei der Implementierung?
Unsere Experten helfen Ihnen bei Design, Implementierung und Betrieb. Von der Architektur bis zur Produktion.
Kontaktieren Sie uns