Hybride Ansaetze: SQL plus Dokumentenspeicher kombinieren
AI generated
SELECT
JOIN
SQL · Polyglot Persistence · Architektur
Hybride Ansaetze: SQL plus Dokumentenspeicher
Polyglot Persistence als bewusste Architekturentscheidung

Eine hybride Architektur haelt transaktionale Kernprozesse in einer relationalen Datenbank, waehrend ein Dokumentenspeicher fuer variable, stark lesende Anwendungsfaelle uebernimmt. Wer Datenaufteilung, Synchronisation und Konsistenzgrenzen bewusst plant, bekommt die Vorteile beider Welten, ohne sich auf einen unsauberen Kompromiss einzulassen.

18 Min. Lesezeit Polyglot Persistence · CDC · Saga-Muster PostgreSQL · MongoDB · Debezium

1. Warum Polyglot Persistence eine Entscheidung ist, kein Kompromiss

Eine Hybrid-Architektur, auch Polyglot Persistence genannt, kombiniert bewusst mehrere Datenbanktypen innerhalb eines Systems, statt eine einzelne Technologie zu zwingen, alle Anforderungen gleichzeitig zu erfuellen. Der Gedanke dahinter ist einfach: Kein einzelnes Datenbankmodell ist fuer jeden Anwendungsfall optimal, also wird jede Domaene mit dem Datenmodell gebaut, das am besten zu ihren spezifischen Zugriffsmustern passt.

Der haeufigste Fehler bei einer Hybrid-Architektur ist, sie als technischen Kompromiss statt als bewusste Entscheidung zu behandeln, mit der Folge, dass Datenaufteilung und Synchronisation nicht sauber geplant werden und am Ende ein fragiles System aus zwei unabhaengig gewachsenen Datenbanken entsteht. Richtig umgesetzt, mit klarer Domaenengrenze, definierten Synchronisationspfaden und bewusst gewaehlten Konsistenzgarantien pro Datenbereich, ist Polyglot Persistence dagegen ein robustes und gut wartbares Architekturmuster.

Dieser Beitrag zeigt, wie man Kernprozesse in einer relationalen Datenbank haelt, waehrend ein Dokumentenspeicher fuer variable, lesehungrige Anwendungsfaelle uebernimmt, inklusive Synchronisationsstrategie, Konsistenzgrenzen und dem operativen Mehraufwand, den eine solche Hybrid-Architektur tatsaechlich mit sich bringt.

2. Grundmuster: wo SQL bleibt und wo der Dokumentenspeicher uebernimmt

Das Grundmuster einer funktionierenden Hybrid-Architektur teilt Verantwortlichkeiten nach Konsistenzbedarf und Zugriffsmuster: Bestellungen, Zahlungen, Bestandsbuchungen und alles mit strenger referentieller Integritaet bleiben in einer relationalen Datenbank mit vollen ACID-Transaktionen. Produktkataloge, Content-Strukturen, Benutzerprofile mit variablen Feldern oder Suchindizes wandern in einen Dokumentenspeicher, der auf schnelle Leseoperationen ueber verschachtelte, heterogene Strukturen optimiert ist.

Diese Aufteilung folgt nicht der Technologie, sondern der Domaene. Ein typisches E-Commerce-System haelt Warenkorb-Zwischenzustaende und Session-Daten oft in einem Key-Value-Store, den Produktkatalog in einem Dokumentenspeicher, und abgeschlossene Bestellungen sowie Zahlungsdaten in einer relationalen Datenbank. Jede Domaene bekommt genau die Konsistenz- und Abfrageeigenschaften, die sie braucht, statt eines Kompromisses, der fuer keinen Bereich optimal ist.


-- Relationale Datenbank: Bestellungen mit strengen Constraints
-- Konsistenz und referentielle Integritaet stehen hier im Vordergrund
CREATE TABLE orders (
  order_id      BIGINT PRIMARY KEY,
  customer_id   BIGINT NOT NULL,
  status        VARCHAR(20) NOT NULL CHECK (status IN ('pending','paid','shipped','cancelled')),
  total_amount  NUMERIC(10,2) NOT NULL CHECK (total_amount >= 0),
  created_at    TIMESTAMP NOT NULL DEFAULT now()
);

CREATE TABLE payments (
  payment_id    BIGINT PRIMARY KEY,
  order_id      BIGINT NOT NULL REFERENCES orders(order_id),
  amount        NUMERIC(10,2) NOT NULL,
  captured_at   TIMESTAMP
);
-- Fremdschluessel und CHECK-Constraints erzwingen Konsistenz,
-- genau das Modell, das fuer Zahlungsdaten unverzichtbar ist

// Dokumentenspeicher: Produktkatalog mit variabler Struktur
// Leseoptimiert, keine referentielle Integritaet noetig
db.catalog.insertOne({
  productId: "sku-4471",
  title: "Trailrunning-Schuh Modell Gamma",
  category: "footwear",
  variants: [
    { size: 42, color: "black", stock: 12 },
    { size: 43, color: "black", stock: 4 }
  ],
  specs: { weightGrams: 285, waterproof: true },
  searchTags: ["trail", "running", "outdoor"]
});
// Ein Dokument liefert die komplette Produktseite in einem Lookup,
// ohne Joins ueber Varianten- und Spec-Tabellen

3. Datenaufteilung nach Domaene statt nach Tabelle

Der entscheidende Planungsschritt einer Hybrid-Architektur ist, die Aufteilung an fachlichen Domaenengrenzen auszurichten, nicht an technischen Tabellengrenzen. Statt zu fragen "welche Tabelle verschieben wir wohin", sollte die Frage lauten "welcher Bounded Context aus dem Domain-Driven-Design-Sinne gehoert zusammen und kann unabhaengig von anderen Bereichen ein eigenes Datenmodell haben". Diese Denkweise verhindert, dass zusammengehoerige Daten ueber zwei Systeme verteilt werden, was Synchronisation unnoetig kompliziert.

Ein Datenfeld sollte in genau einer Hybrid-Architektur-Komponente als "Source of Truth" gelten, auch wenn es in anderen Systemen dupliziert oder projiziert wird. Der Produktpreis etwa lebt als autoritative Quelle im Katalogsystem, wird aber zum Zeitpunkt einer Bestellung in die relationale Datenbank kopiert, damit historische Bestellungen unveraendert bleiben, selbst wenn sich der aktuelle Katalogpreis spaeter aendert. Diese bewusste Duplikation ist kein Designfehler, sondern ein zentrales Muster hybrider Architekturen.

4. Synchronisation zwischen den Systemen mit Change Data Capture

Sobald Daten in zwei Systemen existieren, muss eine Hybrid-Architektur definieren, wie Aenderungen propagiert werden. Der robusteste Ansatz ist Change Data Capture, kurz CDC: Ein Tool wie Debezium liest kontinuierlich das Write-Ahead-Log der relationalen Datenbank und veroeffentlicht jede Aenderung als Event auf einer Message-Queue, von der aus der Dokumentenspeicher aktualisiert wird. Dieser Ansatz vermeidet doppelte Schreiblogik in der Anwendung und garantiert, dass keine Aenderung verloren geht, weil das Log als verlaessliche Quelle dient.

Die Alternative, Dual-Write direkt aus der Anwendung, bei der jede Schreiboperation explizit beide Systeme aktualisiert, ist einfacher zu implementieren, aber fehleranfaelliger: Schlaegt der zweite Schreibvorgang fehl, nachdem der erste bereits committet hat, driften die Systeme auseinander, ohne dass ein Fehler sichtbar wird. CDC loest dieses Problem strukturell, weil es auf dem bereits committeten Zustand der relationalen Datenbank aufsetzt, statt auf zwei unabhaengigen Schreiboperationen im Anwendungscode zu vertrauen.


# Debezium-Connector-Konfiguration fuer CDC von PostgreSQL
# Aenderungen an der orders-Tabelle werden als Events veroeffentlicht
curl -X POST http://connect:8083/connectors \
  -H "Content-Type: application/json" \
  -d '{
    "name": "orders-connector",
    "config": {
      "connector.class": "io.debezium.connector.postgresql.PostgresConnector",
      "database.hostname": "postgres-primary",
      "database.dbname": "shop",
      "table.include.list": "public.orders,public.payments",
      "topic.prefix": "shop-cdc"
    }
  }'

# Ein Consumer-Service liest das Topic shop-cdc.public.orders
# und aktualisiert die passende Projektion im Dokumentenspeicher

5. Konsistenzgrenzen: Saga statt verteilter Transaktion

Eine echte verteilte Transaktion ueber eine relationale Datenbank und einen Dokumentenspeicher hinweg, mit Two-Phase-Commit, ist in der Praxis selten sinnvoll, weil sie Latenz erhoeht und beide Systeme eng koppelt. Das etablierte Muster fuer Hybrid-Architekturen ist stattdessen das Saga-Muster: Eine fachliche Operation wird in mehrere lokale Transaktionen zerlegt, jede in ihrem eigenen System, mit definierten Kompensationsschritten, falls ein spaeterer Schritt fehlschlaegt.

Bestellt ein Kunde ein Produkt, reserviert ein erster Schritt den Lagerbestand im Dokumentenspeicher, ein zweiter Schritt legt die Bestellung in der relationalen Datenbank an. Schlaegt der zweite Schritt fehl, gibt ein Kompensationsschritt die Lagerreservierung im ersten System wieder frei. Diese Kompensationslogik muss explizit im Anwendungscode oder in einer Orchestrierungsschicht implementiert werden, ist aber deutlich robuster und skalierbarer als eine verteilte Transaktion ueber Systemgrenzen hinweg.


-- Pseudocode fuer den Saga-Ablauf (Orchestrierung ausserhalb der Datenbank)
-- Schritt 1: Lagerbestand im Dokumentenspeicher reservieren (separat, s.o.)
-- Schritt 2: Bestellung in der relationalen Datenbank anlegen
BEGIN;
INSERT INTO orders (order_id, customer_id, status, total_amount)
VALUES (8842, 501, 'pending', 149.90);
COMMIT;

-- Kompensationsschritt bei Fehlschlag von Schritt 2:
-- Lagerreservierung im Dokumentenspeicher wieder freigeben
-- (Aufruf erfolgt aus der Orchestrierungsschicht, nicht aus SQL heraus)
-- releaseReservation(productId: "sku-4471", quantity: 1)

6. Die API-Schicht als Abstraktion ueber beide Datenquellen

Damit Client-Anwendungen nicht wissen muessen, welches Feld aus welcher Datenbank stammt, sollte eine Hybrid-Architektur immer eine API-Schicht besitzen, die beide Datenquellen zu einem einheitlichen Antwortformat zusammenfuehrt. Ein GraphQL-Resolver oder ein REST-Aggregations-Endpunkt kann etwa Produktdaten aus dem Dokumentenspeicher mit Preis- und Verfuegbarkeitsdaten aus der relationalen Datenbank kombinieren, ohne dass der Client zwei separate Anfragen stellen muss.

Diese Abstraktionsschicht ist auch der richtige Ort, um Ausfaelle einzelner Systeme abzufedern: Ist der Dokumentenspeicher kurzzeitig nicht erreichbar, kann die API-Schicht mit einem Fallback auf zwischengespeicherte Katalogdaten reagieren, statt den gesamten Request scheitern zu lassen. Diese Resilienz-Logik gehoert konzeptionell zur Hybrid-Architektur dazu und sollte von Anfang an mitgeplant werden, nicht als nachtraeglicher Patch.

7. Praxisbeispiel: Katalog im Dokumentenspeicher, Bestellungen in SQL

Ein konkretes Beispiel verdeutlicht die Hybrid-Architektur in der Praxis: Ein mittelgrosser Online-Shop haelt seinen Produktkatalog mit stark variierenden Attributen, Bildergalerien und Suchmetadaten in MongoDB, weil neue Produktkategorien haeufig neue, unvorhersehbare Felder mitbringen. Bestellungen, Zahlungen, Retouren und Kundendaten liegen in PostgreSQL, weil hier referentielle Integritaet, Transaktionen und rechtliche Nachweispflichten im Vordergrund stehen.

Beim Checkout liest die Anwendung den aktuellen Preis und die Verfuegbarkeit aus MongoDB, kopiert beide Werte als Snapshot in die neue Bestellzeile in PostgreSQL, und startet danach den Zahlungsprozess ausschliesslich innerhalb der relationalen Datenbank. Die Suchfunktion des Shops arbeitet ausschliesslich gegen den Dokumentenspeicher, waehrend das Reporting fuer Buchhaltung und Controlling ausschliesslich gegen die relationale Datenbank laeuft. Jedes System bedient exakt die Anfragen, fuer die es gebaut wurde.


# Konsistenz-Check: Stichprobe zwischen beiden Systemen vergleichen
# Ziel: Preis-Snapshot in Bestellungen darf nicht vom aktuellen
# Katalogpreis zum Bestellzeitpunkt abweichen (ausser durch Preisaenderung)
psql -d shop -c "SELECT order_id, product_sku, price_snapshot FROM order_items WHERE order_id = 8842;"

mongosh --eval 'db.catalog.findOne({productId: "sku-4471"}, {price: 1})'

# Ein automatisiertes Abgleich-Script laesst beide Abfragen periodisch
# laufen und meldet Abweichungen ausserhalb erwarteter Preisaenderungen

8. Operativer Mehraufwand: zwei Systeme statt eines

Der ehrlichste Nachteil einer Hybrid-Architektur ist der operative Mehraufwand: Zwei Datenbanktypen bedeuten zwei Backup-Strategien, zwei Monitoring-Dashboards, zwei Sets an Betriebs-Know-how und zwei potenzielle Ausfallquellen. Ein Team muss sowohl relationale als auch dokumentbasierte Datenbanken beherrschen, inklusive ihrer jeweiligen Failure-Modes, Backup-Verfahren und Skalierungscharakteristika.

Dieser Mehraufwand ist gerechtfertigt, wenn die beiden Domaenen tatsaechlich grundverschiedene Anforderungen haben, die keine einzelne Datenbank gut abdecken wuerde. Er ist nicht gerechtfertigt, wenn eine Hybrid-Architektur nur eingefuehrt wird, weil ein Teammitglied lieber mit MongoDB arbeitet, ohne dass ein echter fachlicher Grund dahintersteht. Die Entscheidung fuer Polyglot Persistence sollte immer eine bewusste Kosten-Nutzen-Abwaegung sein, keine Geschmacksfrage.

9. Hybrid-Architektur versus Single-Store im Vergleich

Die folgende Tabelle stellt eine Hybrid-Architektur einer reinen Single-Store-Loesung gegenueber und zeigt die zentralen Trade-offs.

Aspekt Single-Store (nur SQL) Hybrid-Architektur (SQL plus Dokumentenspeicher)
Passung pro Domaene Ein Modell fuer alle Anwendungsfaelle, teils suboptimal Jede Domaene bekommt das passende Datenmodell
Transaktionale Konsistenz Durchgehend ACID ueber alle Daten ACID pro System, Saga-Muster fuer domaenenuebergreifende Ablaeufe
Betriebsaufwand Ein System, ein Backup-Konzept Zwei Systeme, zwei Betriebskonzepte, CDC-Pipeline
Synchronisationsrisiko Nicht relevant, ein System Muss aktiv gemanagt werden, CDC oder Dual-Write mit Monitoring

Die Wahl faellt zugunsten der Hybrid-Architektur aus, sobald die Domaenen tatsaechlich verschiedene Anforderungen haben und der zusaetzliche Betriebsaufwand durch bessere Passung pro Bereich klar aufgewogen wird. Fuer kleinere Systeme mit homogenen Anforderungen bleibt ein Single-Store meist die einfachere und robustere Wahl.

10. Zusammenfassung

Eine Hybrid-Architektur kombiniert eine relationale Datenbank fuer transaktionale Kernprozesse mit einem Dokumentenspeicher fuer variable, lesehungrige Anwendungsfaelle, ausgerichtet an fachlichen Domaenengrenzen statt an technischen Tabellengrenzen. Change Data Capture synchronisiert Aenderungen zuverlaessiger als Dual-Write, das Saga-Muster ersetzt verteilte Transaktionen ueber Systemgrenzen hinweg, und eine API-Schicht abstrahiert beide Datenquellen fuer Client-Anwendungen.

Der Preis dieser Flexibilitaet ist realer operativer Mehraufwand: zwei Systeme, zwei Betriebskonzepte, eine Synchronisationspipeline, die aktiv ueberwacht werden muss. Wer diese Kosten bewusst gegen den Nutzen einer besseren Passung pro Domaene abwaegt, statt Polyglot Persistence aus Trend oder persoenlicher Praeferenz einzufuehren, bekommt mit einer Hybrid-Architektur ein robustes, gut wartbares System, das die Staerken beider Datenbankwelten tatsaechlich nutzt.

Hybride Ansaetze SQL plus Dokumentenspeicher, das Wichtigste auf einen Blick

Domaenengrenze

Datenaufteilung folgt fachlichen Bounded Contexts, nicht technischen Tabellengrenzen.

Synchronisation

Change Data Capture ueber das Write-Ahead-Log ist robuster als Dual-Write aus der Anwendung.

Konsistenz

Saga-Muster mit Kompensationsschritten statt verteilter Transaktion ueber Systemgrenzen.

Betriebsaufwand

Zwei Systeme bedeuten echten Mehraufwand, muss durch klaren fachlichen Nutzen gerechtfertigt sein.

11. FAQ: Hybride Ansaetze SQL plus Dokumentenspeicher

1Was bedeutet Polyglot Persistence?
Bewusste Kombination mehrerer Datenbanktypen, jede Domaene bekommt das passende Datenmodell statt eines erzwungenen Universalmodells.
2Wie entscheidet man die Datenaufteilung?
Nach Konsistenzbedarf und Zugriffsmuster, Kernprozesse in SQL, variable lesehungrige Daten im Dokumentenspeicher.
3Was ist Change Data Capture?
Liest Aenderungen aus dem Write-Ahead-Log und propagiert sie als Events, robuster als Dual-Write aus der Anwendung.
4Geht eine echte verteilte Transaktion?
Technisch ja, praktisch selten sinnvoll. Das Saga-Muster mit Kompensationsschritten ist der etablierte Ersatz.
5Was ist ein Kompensationsschritt?
Ein expliziter Rueckgaengig-Schritt bei Fehlschlag eines spaeteren Schritts, etwa das Freigeben einer Reservierung.
6Braucht jede Anwendung eine Hybrid-Architektur?
Nein, fuer moderate Variabilitaet reicht oft eine JSON-Spalte, lohnt sich erst bei grundverschiedenen Domaenenanforderungen.
7Wie abstrahiert man zwei Datenquellen?
Ueber eine API-Schicht wie GraphQL oder REST-Aggregation, die beide Quellen zu einer einheitlichen Antwort zusammenfuehrt.
8Groesster operativer Nachteil?
Zwei Backup-Strategien, zwei Monitoring-Setups, mehr Betriebs-Know-how, muss durch fachlichen Nutzen gerechtfertigt sein.
9Was passiert bei Ausfall eines Systems?
Die API-Schicht sollte Fallback-Strategien wie Caching vorsehen, statt den gesamten Request scheitern zu lassen.
10Wie prueft man Synchronitaet zwischen Systemen?
Mit einem automatisierten Abgleich-Script, das Stichproben periodisch vergleicht und Abweichungen aktiv meldet.