Grundlagen

NoSQL und das CAP-Theorem

Warum es neben Tabellen auch Dokumente, Schlüssel-Wert-Speicher und Graphen gibt – und welche Entscheidung jede verteilte Datenbank treffen muss, wenn das Netz zwischen ihren Rechnern reißt.

Lesestand

NoSQL ist ein Sammelbegriff für Datenbanken, die keine klassischen Tabellen benutzen: Schlüssel-Wert-Speicher, Dokument-Datenbanken, Spalten-Datenbanken und Graph-Datenbanken. Jede ist für ein bestimmtes Zugriffsmuster gebaut und lässt sich oft leichter auf viele Rechner verteilen als eine relationale Datenbank.

Sobald Daten auf mehreren Rechnern liegen, gilt das CAP-Theorem: Reißt das Netz zwischen ihnen, muss das System wählen – entweder alle sehen garantiert denselben Stand (Konsistenz), oder jeder Rechner antwortet weiter, auch wenn sein Stand veraltet sein könnte (Verfügbarkeit). Beides zugleich geht nicht.

Warum es NoSQL gibt

Relationale Datenbanken wachsen klassisch vertikal: größerer Server, mehr Speicher, schnellere Platten. Irgendwann gibt es keinen größeren Server mehr. Mitte der 2000er-Jahre standen Google und Amazon genau dort und bauten eigene Systeme, die horizontal wachsen – einfach mehr gewöhnliche Rechner dazu. Die Beschreibungen von Googles Bigtable (2006) und Amazons Dynamo (2007) wurden zu Bauplänen einer ganzen Generation. 2009 bekam die Bewegung ihren Namen, heute meist gelesen als „Not only SQL“.

Der Preis: Was relationale Datenbanken mühelos können – JOINs über beliebige Tabellen, Transaktionen über beliebige Zeilen –, wird auf vielen Rechnern teuer. NoSQL-Systeme verzichten deshalb oft darauf und verlangen, dass man die Daten so ablegt, wie man sie später abfragt.

Die vier Familien

Dieselben Daten – Kundin Anna mit zwei Bestellungen – in fünf Modellen:

Ein Datensatz, fünf Datenmodelle

Daten verteilen: Replikation und Sharding

Zwei Techniken stecken hinter jeder verteilten Datenbank, oft kombiniert:

⧉

Replikation

Dieselben Daten liegen auf mehreren Rechnern. Fällt einer aus, übernehmen die anderen, und Lesezugriffe verteilen sich. Die Schwierigkeit: alle Kopien aktuell halten.

▤

Sharding

Die Daten werden aufgeteilt: Kunden A–M auf Rechner 1, N–Z auf Rechner 2. Jeder Rechner trägt nur einen Teil der Last. Die Schwierigkeit: Anfragen über mehrere Teile.

#

Hash-Verteilung

Statt nach Alphabet verteilt man meist nach einem Hash des Schlüssels – so landen die Daten gleichmäßig verteilt, ohne dass ein Rechner alle „M“-Namen abbekommt.

Die naheliegende Formel lautet: Rechner = Hash(Schlüssel) mod Anzahl. Das funktioniert – bis ein Rechner dazukommt. Dann ändert sich das Ergebnis für fast jeden Schlüssel, und fast alle Daten müssten umziehen. Consistent Hashing löst das: Rechner und Schlüssel werden auf einen gedachten Ring abgebildet, jeder Schlüssel gehört dem nächsten Rechner im Uhrzeigersinn. Ein neuer Rechner übernimmt nur ein Stück des Rings.

1000 Kunden auf Rechner verteilen

Hash mod Anzahl

Consistent Hashing

Echte Berechnung mit 1000 Schlüsseln. Beim Consistent Hashing hat jeder Rechner 100 Punkte auf dem Ring („virtuelle Knoten“), damit die Verteilung gleichmäßig wird – so machen es etwa Cassandra und DynamoDB.

Das CAP-Theorem

Eric Brewer stellte im Jahr 2000 eine Vermutung auf, die Seth Gilbert und Nancy Lynch 2002 bewiesen. Ein verteiltes System kann von diesen drei Eigenschaften nicht alle gleichzeitig garantieren:

C

Consistency

Jedes Lesen liefert den neuesten geschriebenen Wert – oder einen Fehler. Alle sehen dasselbe.

A

Availability

Jede Anfrage an einen funktionierenden Rechner bekommt eine Antwort – keinen Fehler.

P

Partition tolerance

Das System arbeitet weiter, auch wenn das Netz zwischen seinen Rechnern unterbrochen ist.

Wichtig ist, wie man das liest. Netzunterbrechungen passieren – man kann P nicht abwählen. Die eigentliche Aussage ist: Wenn das Netz reißt, muss man zwischen C und A wählen. Spiel es durch:

Das Netz reißt

Keine der beiden Antworten ist falsch, es kommt auf die Daten an. Ein Kontostand oder der letzte Sitzplatz verlangt CP – lieber eine Fehlermeldung als eine Doppelbuchung. Ein Warenkorb, ein Like-Zähler oder ein Social-Media-Feed verträgt AP – lieber kurz veraltet als „Seite nicht verfügbar“. Amazon hat Dynamo genau deshalb als AP-System gebaut: Ein Warenkorb, der Artikel doppelt enthält, ist ärgerlich; einer, der sich nicht öffnen lässt, kostet Umsatz.

Eine Erweiterung, PACELC, ergänzt den Normalfall: Auch ohne Netzunterbrechung muss man abwägen – zwischen niedriger Latenz und strenger Konsistenz. Denn auf die Bestätigung aller Kopien zu warten, kostet bei jedem Schreiben Zeit.

Quoren: Konsistenz zum Einstellen

Viele Systeme lassen die Wahl pro Anfrage offen. Bei N Kopien bestätigt ein Schreiben, sobald W Kopien es haben, und ein Lesen fragt R Kopien. Ist R + W größer als N, überschneiden sich Lese- und Schreibmenge immer – mindestens eine gefragte Kopie kennt den neuesten Wert.

N, W und R
Kopien (N)
Schreiben wartet auf (W)
Lesen fragt (R)
hat das neueste Schreibenwird beim Lesen gefragtbeides

Ungünstigster Fall gezeigt: Das Lesen fragt bevorzugt die Kopien, die das Schreiben nicht erreicht hat.

Konsistenzmodelle

Zwischen „alle sehen sofort dasselbe“ und „irgendwann stimmt es“ gibt es Abstufungen, die in der Praxis viel ausmachen:

ModellGarantieSpürbar als
Stark (linearisierbar)Jedes Lesen sieht das neueste Schreibenverhält sich wie eine einzige Datenbank
Read your writesIch sehe immer meine eigenen Änderungenkein „Ich habe doch gerade gespeichert – wo ist es?“
Monotones LesenIch sehe nie einen älteren Stand als vorhinKommentare verschwinden nicht beim Neuladen
Eventual ConsistencyOhne neue Schreibvorgänge stimmen irgendwann alle Kopien übereinkurz veraltete Zähler, Listen, Feeds

Wann was?

BedarfTypische Wahl
Geschäftsdaten mit Beziehungen und Transaktionenrelational – PostgreSQL, MySQL, Oracle
Cache, Sitzungen, Zähler, RanglistenSchlüssel-Wert im Speicher – Redis, Valkey
Objekte mit wechselnder Struktur, als Ganzes gelesenDokument – MongoDB, oder jsonb in PostgreSQL
Riesige Schreiblast, Messwerte, Ereignisse, weltweit verteiltSpalten – Cassandra, ScyllaDB; Zeitreihen – InfluxDB, TimescaleDB
Beziehungen über viele Ecken: Netzwerke, Empfehlungen, BetrugserkennungGraph – Neo4j
VolltextsucheSuchmaschine – Elasticsearch, OpenSearch
SQL und Transaktionen, aber weltweit verteilt„NewSQL“ – Google Spanner, CockroachDB

Die Grenzen verschwimmen: PostgreSQL speichert und indiziert JSON, MongoDB kann Transaktionen über mehrere Dokumente, und verteilte SQL-Datenbanken zeigen, dass starke Konsistenz und horizontales Wachstum sich nicht ausschließen – sie kosten nur Latenz. Viele Systeme setzen mehrere Datenbanken nebeneinander ein, jede für ihren Zweck.

Für Entwickler übersetzt

// Spring Data MongoDB: ein Dokument mit eingebetteten Bestellungen
@Document("kunden")
record Kunde(@Id String id, String name, List<Bestellung> bestellungen) {}
record Bestellung(long nr, LocalDate datum, BigDecimal summe) {}

interface KundenRepository extends MongoRepository<Kunde, String> {
    List<Kunde> findByName(String name);               // Abfrage aus dem Methodennamen
}

// Spring Data Redis: Schlüssel-Wert mit Ablaufzeit – ein klassischer Cache
redis.opsForValue().set("sitzung:a81f", kundeId, Duration.ofMinutes(30));
ThemaWas man wissen sollte
Spring DataDieselbe Repository-Idee für JPA, MongoDB, Redis, Cassandra, Neo4j und Elasticsearch – die Abfragen unterscheiden sich trotzdem, weil die Modelle sich unterscheiden.
Datenmodell nach AbfrageIn Dokument- und Spalten-Datenbanken entwirft man von den Abfragen her: Was zusammen gelesen wird, gehört zusammen gespeichert. Das Gegenteil der Normalisierung.
Eventual Consistency im CodeNach dem Speichern sofort neu lesen kann den alten Stand liefern. Entweder mit der eigenen Antwort weiterarbeiten oder für dieses Lesen stärkere Konsistenz anfordern.
Schema im Code„Schemalos“ heißt: Die Datenbank prüft nichts. Das Schema steckt dann in den Java-Klassen – alte Dokumente mit alten Feldern muss der Code weiter verstehen.

Häufige Irrtümer

„CAP heißt: Such dir zwei von dreien aus.“ – Netzunterbrechungen sind keine Wahl. Die Entscheidung zwischen C und A fällt nur, wenn das Netz tatsächlich reißt – und im Normalfall geht es um Latenz gegen Konsistenz.
„NoSQL ist schneller als SQL.“ – Für das Zugriffsmuster, für das es gebaut ist. Für ein anderes kann es dramatisch langsamer sein. Eine relationale Datenbank auf einem Server reicht für die allermeisten Anwendungen.
„NoSQL hat kein Schema.“ – Es hat ein implizites Schema im Code. Das ist flexibel, verschiebt aber die Prüfung von der Datenbank in jede Anwendung, die die Daten liest.
„MongoDB kann keine Transaktionen.“ – Seit Version 4.0 von 2018 kann es Transaktionen über mehrere Dokumente. Die meisten NoSQL-Systeme haben über die Jahre nachgerüstet.
„Eventual Consistency heißt: irgendwann, vielleicht.“ – In der Praxis meist Millisekunden. Es heißt aber auch: Ohne Vorkehrung kann ein Nutzer seine eigene Änderung kurz nicht sehen.

Verwandte Begriffe