
Jahrzehntelang war die Datenbankwelt in zwei Lager gespalten: **relationale Datenbanken** (PostgreSQL, MySQL) mit starker Konsistenz, aber begrenzter Skalierbarkeit und **NoSQL-Datenbanken** (MongoDB, Cassandra) mit horizontaler Skalierbarkeit, aber schwächerer Konsistenz und eingeschränkten Abfragemöglichkeiten.
Jahrzehntelang war die Datenbankwelt in zwei Lager gespalten: relationale Datenbanken (PostgreSQL, MySQL) mit starker Konsistenz, aber begrenzter Skalierbarkeit und NoSQL-Datenbanken (MongoDB, Cassandra) mit horizontaler Skalierbarkeit, aber schwächerer Konsistenz und eingeschränkten Abfragemöglichkeiten.
Distributed SQL (auch NewSQL genannt) schließt diese Lücke. Es bietet die volle Leistungsfähigkeit von SQL – ACID-Transaktionen, Joins, Fremdschlüssel und vertraute Tools – auf einer horizontal skalierbaren, verteilten Architektur. Das Ergebnis: die Konsistenz und Abfrageleistung einer relationalen Datenbank mit der Skalierbarkeit von NoSQL.
Strong Consistency
▲
│ ┌───────────────────────┐
│ │ Distributed SQL │
│ │ (CockroachDB, │
│ │ YugabyteDB, │
│ │ Google Spanner) │
│ └───────────────────────┘
│
│ ┌──────────────┐ ┌──────────────────┐
│ │ Traditional │ │ Traditional │
│ │ SQL │ │ NewSQL │
│ │ (PostgreSQL,│ │ (Vitess, TiDB) │
│ │ MySQL) │ │ │
│ └──────────────┘ └──────────────────┘
│
│ ┌──────────────────┐
│ │ NoSQL │
│ │ (Cassandra, │
│ │ DynamoDB, │
│ │ CosmosDB) │
│ └──────────────────┘
└────────────────────────────────────────────────────
Horizontal Scalability ──────►
| Funktion | Beschreibung |
|---|---|
| SQL-Schnittstelle | Vollständige SQL-Unterstützung: JOINs, Unterabfragen, Aggregationen, Fensterfunktionen |
| ACID-Transaktionen | Serialisierbare oder Snapshot-Isolation über Knoten hinweg |
| Horizontale Skalierung | Fügen Sie Knoten ohne Ausfallzeit hinzu, die Daten werden automatisch neu ausgeglichen |
| Auto-Sharding | Daten werden automatisch über Knoten verteilt |
| Replikation | Synchrone Replikation für Haltbarkeit (RPO=0) |
| Hohe Verfügbarkeit | Automatisches Failover, kein manueller Eingriff |
| Geoverteilung | Daten können mehrere Regionen mit einer Latenz von < 50 ms umfassen |
┌──────────────────────────────────────────┐
│ Spanner Global Architecture │
├──────────────────────────────────────────┤
│ Zone 1 (us-east1) Zone 2 (europe-west)│
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Leader Node │ │ Follower Node│ │
│ │ ┌────────┐ │ │ │ │
│ │ │ Spanner│ │ │ │ │
│ │ │ Server │ │ │ │ │
│ │ └────────┘ │ │ │ │
│ └──────────────┘ └──────────────┘ │
├──────────────────────────────────────────┤
│ TrueTime API (GPS + Atomic) │
│ Clock synchronization < 7ms │
└──────────────────────────────────────────┘
Schlüsselinnovation: TrueTime API – GPS- und Atomuhrsynchronisation, die eine begrenzte Uhrenunsicherheit bietet. Dies ermöglicht externe Konsistenz (Linearisierbarkeit) über global verteilte Knoten hinweg.
┌─────────────────────────┐
│ SQL Gateway │
│ (Any node can serve) │
└──────────┬──────────────┘
│
┌──────────────────────┼──────────────────────┐
│ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ Node 1 │ │ Node 2 │ │ Node 3 │
│ ┌───────┐ │ │ ┌───────┐ │ │ ┌───────┐ │
│ │ Range A│ │ │ │ Range A│ │ │ │ Range A│ │
│ │ (LEADER)│ │ │(FOLLOWER│ │ │(FOLLOWER│ │
│ └───────┘ │ │ └───────┘ │ │ └───────┘ │
│ ┌───────┐ │ │ ┌───────┐ │ │ ┌───────┐ │
│ │ Range B│ │ │ │ Range B│ │ │ │ Range B│ │
│ │(FOLLOWER│ │ │ (LEADER)│ │ │(FOLLOWER│ │
│ └───────┘ │ │ └───────┘ │ │ └───────┘ │
└───────────┘ └───────────┘ └───────────┘
So funktioniert CockroachDB:
YugabyteDB ist für PostgreSQL-Kompatibilität auf Wire-Protokollebene konzipiert:
-- This is standard PostgreSQL syntax — it just works
CREATE TABLE orders (
id UUID DEFAULT gen_random_uuid(),
customer_id UUID NOT NULL,
total NUMERIC(10,2) NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
created_at TIMESTAMPTZ DEFAULT NOW(),
PRIMARY KEY (id)
);
-- Distributed ACID transaction across nodes
BEGIN;
INSERT INTO orders (customer_id, total, status)
VALUES ($1, $2, 'pending');
UPDATE inventory SET quantity = quantity - 1
WHERE product_id = $3 AND quantity > 0;
COMMIT;
-- Full PostgreSQL ecosystem compatibility
-- Supports: pgAdmin, Prisma, DBeaver, all standard drivers
| Funktion | KakerlakeDB | YugabyteDB | TiDB | Google-Schlüssel |
|---|---|---|---|---|
| Kompatibilität | PostgreSQL (85 %) | PostgreSQL (95 %+) | MySQL | Proprietär |
| Konsistenz | Serialisierbar | Serialisierbar | Snapshot-Isolation | Äußere Konsistenz |
| Replikation | Floß | Floß | Floß | Paxos |
| Geoverteilung | Ja | Ja | Ja | Ja |
| Auto-Sharding | Ja (nach Bereich) | Ja (nach Hash/Bereich) | Ja (nach Bereich) | Ja (nach Aufteilung) |
| Sekundäre Indizes | Global (verteilt) | Global + Lokal | Global + Lokal | Global |
| Fremdschlüssel | Ja | Ja | Ja | Ja |
| CDC | Ja (Kafka-Waschbecken) | Ja (Kafka, Elastic) | Ja (TiCDC) | Ja (Pub/Sub) |
| Lizenzierung | BSL (Quelle verfügbar) | Apache 2.0 | Apache 2.0 | Proprietär |
| Cloud-verwaltet | CockroachDB Cloud | YugabyteDB verwaltet | TiDB-Cloud | Cloud Spanner |
| Selbstveranstalter | Ja | Ja | Ja | Nein |
| Anwendungsfall | Warum verteiltes SQL | Beispiel |
|---|---|---|
| Globale SaaS-Anwendungen | Benutzer auf der ganzen Welt benötigen niedrige Latenzzeiten und starke Konsistenz | Benutzerkonten für mehrere Regionen |
| Finanzsysteme | ACID-Transaktionen über Shards hinweg, kein Datenverlust | Zahlungsabwicklung, Hauptbuch |
| E-Commerce-Plattformen | Inventar, Bestellungen, Warenkörbe – alles braucht Konsistenz | Der Verkehr am Black Friday nimmt zu |
| Gaming | Spielerstatus, Bestenlisten, Transaktionen | Regionsübergreifender Multiplayer |
| IoT-Zeitreihen + Metadaten | SQL für Analysen verteilter Daten | Flottentelemetrie mit Joins |
| Szenario | Warum | Bessere Alternative |
|---|---|---|
| Einfache Schlüsselwertsuche | Overhead verteilter Transaktionen nicht gerechtfertigt | Redis, DynamoDB |
| Einzelregion, kleine Datenmengen | Komplexität ist nicht erforderlich | PostgreSQL |
| Volltextsuche | Nicht für die Textindizierung konzipiert | Elasticsearch |
| Diagrammdurchläufe | JOINs in tiefen Beziehungen sind langsam | Neo4j |
| Sehr hoher Schreibdurchsatz (>100.000 Schreibvorgänge/Sek./Knoten) | Der Konsensaufwand könnte zu hoch sein | Cassandra, ScyllaDB |
-- Data is split by primary key ranges
Table: orders
Range 1: PK '00000000' to '3fffffff' → Node 1 (LEADER) + Node 2, Node 3
Range 2: PK '40000000' to '7fffffff' → Node 2 (LEADER) + Node 1, Node 3
Range 3: PK '80000000' to 'bfffffff' → Node 3 (LEADER) + Node 1, Node 2
Range 4: PK 'c0000000' to 'ffffffff' → Node 1 (LEADER) + Node 2, Node 3
Vorteile: Effiziente Bereichsscans, gut für sequentielle Tasten. Nachteile: Schreiben Sie Hotspots, wenn Sie sequentielle Schlüssel einfügen (gelöst durch Hash-Sharded-Indizes).
-- Hash-sharded primary key
CREATE TABLE orders (
id UUID DEFAULT gen_random_uuid(),
customer_id UUID,
total NUMERIC,
PRIMARY KEY (id HASH)
);
-- Data distribution by hash
Hash('00000000-...') = 0.23 → Tablet 1 → Node 1
Hash('11111111-...') = 0.67 → Tablet 2 → Node 2
Hash('22222222-...') = 0.12 → Tablet 3 → Node 3
Vorteile: Gleichmäßige Datenverteilung, keine Hotspots. Nachteile: Bereichsscans über die gesamte Tabelle sind ineffizient.
-- This transaction spans multiple nodes
BEGIN;
UPDATE account_a SET balance = balance - 100 WHERE id = 'A';
UPDATE account_b SET balance = balance + 100 WHERE id = 'B'; -- Different node
COMMIT;
-- Under the hood:
-- 1. Transaction coordinator (any node) acquires locks
-- 2. Prepares both participants
-- 3. Raft commits the transaction record
-- 4. COMMIT acknowledged to client
-- All-or-nothing — guaranteed ACID
Indizes selbst sind über Knoten verteilt:
CREATE INDEX idx_orders_customer ON orders (customer_id);
-- Query that uses the distributed index:
SELECT * FROM orders WHERE customer_id = $1;
-- 1. Routes to any node
-- 2. Node looks up customer_id in distributed index
-- 3. Index returns primary keys → fetch from correct ranges
-- 4. Returns results
Verteiltes SQL unterstützt Schemaänderungen ohne Ausfallzeiten:
-- Add a column — non-blocking
ALTER TABLE orders ADD COLUMN discount NUMERIC(5,2) DEFAULT 0.00;
-- Create index — non-blocking (background build)
CREATE INDEX CONCURRENTLY idx_orders_date ON orders (created_at);
Datenbankänderungen an nachgelagerte Systeme weiterleiten:
-- CockroachDB CDC
CREATE CHANGEFEED FOR TABLE orders, payments
INTO 'kafka://kafka-cluster:9092'
WITH updated, resolved, min_checkpoint_frequency = '5s';
-- YugabyteDB CDC connector
# Deploy to Kafka Connect
{
"name": "yb-cdc-connector",
"config": {
"connector.class": "io.yugabyte.cdc.YBChangeDataCaptureConnector",
"database.hostname": "yb-1.example.com",
"database.port": "5433",
"table.include.list": "public.orders"
}
}
Einzelne Region (3 Knoten):
replication:
factor: 3
constraints:
- "+region=us-east-1: 3"
# All data in one region, 3 copies, survives 2 node failures
Multiregional (Ausfall der Überlebensregion):
replication:
factor: 3
constraints:
- "+region=us-east-1: 1"
- "+region=us-west-1: 1"
- "+region=eu-west-1: 1"
# One copy in each region, survives any single region failure
# Write latency: round-trip to the farthest region
Multiregional mit engem Quorum (für Schreibvorgänge mit geringer Latenz):
replication:
factor: 5
constraints:
- "+region=us-east-1: 3" # 3 copies here
- "+region=us-west-1: 1" # 1 copy for DR
- "+region=eu-west-1: 1" # 1 copy for DR
# Write quorum = 3, achievable within us-east-1
# Write latency = intra-region
| Topologie | Schreiblatenz (S. 50) | Leselatenz (S. 50) |
|---|---|---|
| Einzelner Knoten | 1-5ms | 0,5–2 ms |
| 3 Knoten, gleiche Region | 5-15ms | 1-5ms |
| 3 Knoten, 3 Regionen (USA, EU, APAC) | 100–300 ms | 5-50 ms (am nächsten) |
| 5 Knoten, 2 Regionen (enges Quorum) | 5-15ms | 1-5ms |
Phase 1: Evaluate
- Identify tables that need horizontal scaling
- Assess which queries cross shards
- Plan sharding key
Phase 2: Migrate schema
- Convert CREATE TABLE statements
- Choose primary key strategy (hash vs. range)
- Handle sequences (use UUIDs instead of SERIAL)
Phase 3: Migrate data
- Use CDC or batch export/import
- Verify consistency
- Set up replication from old DB
Phase 4: Cut over
- Point application to new DB
- Monitor performance
- Keep old DB as rollback target for 1 week
-- PostgreSQL → CockroachDB
-- ❌ Sequences (not distributed)
SERIAL PRIMARY KEY → UUID DEFAULT gen_random_uuid()
-- ❌ Array functions not supported
array_agg(DISTINCT x) → json_agg(DISTINCT x) -- workaround
-- ❌ Long-running queries
-- Solution: add index or query hint
-- ❌ Cross-database queries (CockroachDB)
-- Each cluster = one database, no cross-DB queries
Verteiltes SQL stellt die Konvergenz von zwei Jahrzehnten Datenbankentwicklung dar – es kombiniert die Zuverlässigkeit und Ausdruckskraft von SQL mit der Elastizität und Belastbarkeit verteilter Systeme.
Q: Do you need horizontal write scaling?
├─ Yes
│ Q: Do you need ACID across all data?
│ ├─ Yes → Distributed SQL (CockroachDB, Spanner)
│ └─ No → NoSQL (Cassandra, DynamoDB)
└─ No
Q: Do you need SQL features (joins, aggregations)?
├─ Yes → PostgreSQL
└─ No → Key-value or document store
Verteiltes SQL ist die Datenbankarchitektur für das globale, cloudnative Zeitalter – Anwendungen, die überall funktionieren müssen, mit starker Konsistenz und ohne Kompromisse.
Noch keine freigegebenen Kommentare sichtbar. Neue Antworten können moderiert werden.