Inhaltsverzeichnis14 Abschnitte
- TL;DR
- Natural Keys: was sie sind und wo sie brechen
- Wo Natural Keys gut funktionieren
- Wo Natural Keys brechen
- Surrogate Keys: System-generiert, Business-agnostisch
- Surrogate Keys in SCD Type 2
- UUID vs Auto-Increment Integer
- Hash-Keys in Data Vault
- Entscheidungs-Guide
- Das Schlimmste aus beiden Welten: Composite Natural Keys
- Praktische Empfehlung
- FAQ
- Fazit
- Weiterlesen
Surrogate vs Natural Keys: Wann was nutzen
Du erbst ein Data-Warehouse, in dem jede Dimension-Tabelle den customer_code des Source-Systems als Primary Key nutzt. Dann wird das Source-System migriert und Codes neu zugewiesen. Jetzt baust du die Hälfte deines Modells um. Das ist das Natural-Key-Problem.
Aber Surrogate-Keys haben eigene Failure-Modes. Die Debatte ist älter als die meisten modernen Daten-Stacks — und die richtige Antwort hängt genuin vom Kontext ab.
TL;DR
| Natural Key | Surrogate Key | |
|---|---|---|
| Definition | Key, der real existiert (E-Mail, Steuer-ID, Produkt-Code) | System-generierter Identifier ohne Business-Bedeutung |
| Beispiele | customer_email, ISIN, order_reference | Auto-Increment INT, UUID, Hash-Key |
| Stabilität | Business-kontrolliert, kann sich ändern | System-kontrolliert, ändert sich nie |
| Debugbarkeit | Hoch — Menschen lesbar | Niedrig — Join zurück nötig |
| Join-Performance | Hängt von Datentyp und Cardinality ab | INT/BIGINT schnell; UUID langsamer |
| Empfohlen für | Lookup-Tabellen, Reference-Daten, kleine Dimensions | Fact-Tabellen, große Dimensions, SCD-Tracking |
Natural Keys: was sie sind und wo sie brechen
Ein Natural Key ist eine Spalte (oder Kombination), die einen Record per Real-World-Bedeutung eindeutig identifiziert. Ein ISIN identifiziert ein Finanzinstrument. Eine E-Mail-Adresse identifiziert einen User. Ein Produkt-Barcode identifiziert ein Produkt.
Wo Natural Keys gut funktionieren
-- PostgreSQL: ISO-Währungscodes als Natural Key
-- Währungen ändern ihre Codes nicht. USD ist USD. EUR ist EUR.
CREATE TABLE currencies (
currency_code CHAR(3) PRIMARY KEY, -- Natural Key: ISO 4217
currency_name TEXT NOT NULL,
decimal_places SMALLINT
);
-- Sicherer Join — currency_code ist stabil und universell verstanden
SELECT t.amount, c.currency_name
FROM transactions t
JOIN currencies c ON t.currency_code = c.currency_code;
ISO-Codes, Länder-Codes, Standard-Enums — sind genuin stabil. Natural Keys schaffen hier Klarheit ohne Risiko.
Wo Natural Keys brechen
Natural Keys versagen, wenn das Business den Wert kontrolliert und das Business sich ändert:
- Wiederverwendung — Ein User löscht den Account. Neuer User registriert mit gleicher E-Mail. Historie kontaminiert.
- Korrektur — Eine Steuer-ID wurde mit Tippfehler erfasst. Fix kaskadiert durch jeden Foreign Key.
- Merger-Events — Zwei Firmen mergen. Ihre
company_id-Werte müssen konsolidiert werden. Jede Downstream-Tabelle bricht. - Multi-Source-Integration — System A nutzt
USER_001; System B nutztU-00001. Beide meinen dieselbe Person. Keiner ist verlässlicher Primary Key im integrierten Modell.
-- PostgreSQL: Multi-Source-Problem
-- Natural Keys gehen nicht, wenn zwei Systeme verschiedene ID-Schemata
-- für dieselbe Real-World-Entität nutzen
-- Source A
INSERT INTO customers VALUES ('USER_001', 'Alice', 'alice@example.com');
-- Source B (gleiche Person, anderes System)
INSERT INTO customers VALUES ('U-00001', 'Alice', 'alice@example.com');
-- Welcher ist der Primary Key? Keiner.
-- Du brauchst einen Surrogate, um die unified Entity zu repräsentieren.
Surrogate Keys: System-generiert, Business-agnostisch
Ein Surrogate Key ist ein bedeutungsloser Identifier vom Datensystem. Die häufigsten Formen:
- Auto-Increment Integer (
SERIAL,IDENTITY) — schnell, kompakt, sequenziell - UUID — global eindeutig, safe für verteilte Generierung, aber größer
- Hash-Key (Data Vault) — abgeleitet von Natural-Key-Attributen, deterministisch
-- PostgreSQL: Surrogate Key mit IDENTITY
CREATE TABLE customers (
customer_sk BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, -- Surrogate
customer_id TEXT UNIQUE NOT NULL, -- Natural Key, weiterhin gespeichert!
customer_name TEXT,
email TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
Beachte, dass customer_id (Natural Key) als reguläre Spalte gespeichert wird — nicht als Primary Key. Standard-Pattern: Surrogate als Join-Key, Natural Key für Lookups und Debugging.
Surrogate Keys in SCD Type 2
Slowly Changing Dimensions (SCD Type 2) sind ohne Surrogate Keys unmöglich. Wenn ein Kunde die Adresse ändert, fügst du eine neue Version der Zeile mit neuem Surrogate Key ein — alte und neue Zeile haben gleichen Natural Key aber unterschiedliche Surrogates.
-- PostgreSQL: SCD Type 2 mit Surrogate Key
CREATE TABLE dim_customer (
customer_sk BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
customer_id TEXT NOT NULL, -- Natural Key (über Versionen gleich)
customer_name TEXT,
city TEXT,
valid_from DATE NOT NULL,
valid_to DATE, -- NULL = current
is_current BOOLEAN DEFAULT TRUE
);
-- Kunde zieht Berlin → Hamburg: neue Zeile, gleicher customer_id
INSERT INTO dim_customer (customer_id, customer_name, city, valid_from, valid_to, is_current)
VALUES
('CUST-042', 'Markus Bauer', 'Berlin', '2023-01-01', '2024-06-30', FALSE),
('CUST-042', 'Markus Bauer', 'Hamburg', '2024-07-01', NULL, TRUE);
Ohne Surrogate customer_sk würden deine Fact-Tabellen-Referenzen bei jeder Versionierung brechen.
UUID vs Auto-Increment Integer
Beide sind Surrogate Keys, verhalten sich aber bei Scale unterschiedlich.
| Auto-Increment (BIGINT) | UUID (v4) | |
|---|---|---|
| Größe | 8 Bytes | 16 Bytes |
| Join-Performance | Schnell (Integer-Vergleich) | Langsamer (String/Byte-Vergleich) |
| Index-Fragmentierung | Niedrig (sequenzielle Inserts) | Hoch (Random Inserts) |
| Verteilte Generierung | Braucht Koordination | Keine Koordination nötig |
| Debugbarkeit | Niedrig | Etwas besser (global eindeutig) |
| Am besten für | Single-Writer-Systeme | Verteilte / Multi-Source-Systeme |
UUID v7 (zeitlich geordnete UUIDs) wird zunehmend populär, da es globale Eindeutigkeit mit sequenzieller Insert-Reihenfolge kombiniert und Index-Fragmentierung reduziert.
Hash-Keys in Data Vault
Data Vault 2.0 nutzt Hash-Keys — eine spezifische Surrogate-Key-Form, abgeleitet vom Natural Key per deterministischer Hash-Function (typisch SHA-256 oder MD5). Der Hash wird zur Load-Zeit berechnet und als Hub-Primary-Key genutzt.
# Python: Data-Vault-Hash-Key berechnen
import hashlib
def compute_hash_key(business_key: str) -> str:
# Deterministischer Hash-Key für Data-Vault-Hub
normalized = business_key.strip().upper() # vor Hash normalisieren
return hashlib.sha256(normalized.encode("utf-8")).hexdigest()
# Beispiel
customer_hk = compute_hash_key("CUST-042")
print(customer_hk)
# => 3e7c... (gleich jedes Mal für gleichen Input)
Vorteil: Hash-Keys sind deterministisch über Source-Systeme. Wenn System A und System B beide CUST-042 laden, generieren sie denselben Hash — Integration ohne zentralen Sequence-Generator.
Entscheidungs-Guide
Als Startpunkt, nicht starre Regel:
| Situation | Empfehlung |
|---|---|
| Reference/Lookup-Tabelle mit stabilen Codes (ISO, Enum) | Natural Key okay |
| Fact-Tabelle in Star-Schema | Surrogate Key (Integer) |
| SCD Type 2 Dimension | Surrogate Key — Pflicht |
| Multi-Source-Integration (Data Vault) | Hash-Key |
| Verteilte Microservices generieren IDs | UUID (v4 oder v7) |
| Kleine Config-Tabelle mit < 1000 Zeilen | Natural Key okay |
| Customer/User-Entität in transaktionaler DB | Surrogate + Natural Key als separate Spalte |
Das Schlimmste aus beiden Welten: Composite Natural Keys
Ein Composite Natural Key kombiniert mehrere Spalten für Eindeutigkeit — z.B. (order_date, order_number). Die fragilste Wahl:
- Jeder Foreign Key muss alle Spalten tragen
- Änderungen an einer Komponente kaskadieren überall
- Joins werden Multi-Column, schwerer zu indexen und lesen
Wenn du Composite Natural Keys erbst, ersetze sie durch Surrogates in der ersten Integration-Schicht. Originale als Non-Key-Spalten behalten.
Praktische Empfehlung
In den meisten analytischen Datenmodellen: Surrogate Keys als Primary Keys, Natural Keys als Attribute gespeichert. Das entkoppelt dein Modell von Upstream-Systemen und macht SCD-Tracking unkompliziert.
Die eine Ausnahme: stabile Reference-Tabellen (ISO-Währungen, Länder-Codes, Calendar-Dates). Natural Keys sind dort tatsächlich klarer und sicherer als beliebige Integers.
Wenn du ein bestehendes Modell auditest und Key-Verteilung, Eindeutigkeit oder Join-Fan-outs über Tabellen prüfen musst, lässt dich Harbinger Explorer CSV- oder Parquet-Exports direkt im Browser abfragen — nützlich für schnelles Ad-hoc-Profiling ohne dediziertes BI-Tool.
FAQ
Sollte ich für transaktionale Apps UUID oder Auto-Increment nutzen? Für Single-DB: Auto-Increment (kleiner, schneller). Für verteilte Apps oder Microservices: UUID v7.
Was ist mit Snowflake-IDs (Twitter-Stil)? Gute Wahl für hochskalierte Systeme — sortierbar wie Auto-Increment, verteilt generierbar wie UUID.
Wie hänge ich Natural und Surrogate Keys zusammen? Natural Key als unique-constrained Spalte zusätzlich zum Surrogate PK. Lookups gehen über Natural Key, Joins über Surrogate.
Was bei Datenbank-Migration? Surrogate Keys können neu generiert werden, Natural Keys bleiben stabil — das macht Migrations einfacher.
DSGVO und Surrogate Keys? Surrogate Keys können helfen, sensible Natural Keys (E-Mail, Steuer-IDs) zu schützen — Joins über opake IDs statt PII.
Fazit
Weder Surrogate noch Natural Keys sind universell korrekt. Natural Keys fügen semantische Klarheit hinzu, binden dein Modell aber an Business-Logic, die sich ändern kann. Surrogate Keys entkoppeln Struktur von Bedeutung, fügen aber Indirection hinzu. Das Pattern, das am besten skaliert: beide behalten — Surrogate als Join-Key, Natural Key als queryable Attribut.
Der echte Fehler ist, das als Einmal-Entscheidung zu behandeln. Wenn dein Modell sich entwickelt, revidiere Key-Strategie bei jeder neuen Source oder Stabilitätsproblem.
Weiterlesen
Stand: 14. Mai 2026.
Geschrieben von
Harbinger Team
Cloud-, Data- und AI-Engineer in DACH. Schreibt seit 2018 über infrastrukturkritische Tech-Entscheidungen — keine Marketing- Folien, sondern echte Trade-offs aus Production-Workloads.
Hat dir das geholfen?
Jede Woche ein neuer Artikel über DACH-Cloud, Data und AI — direkt in dein Postfach. Kein Spam, kein Marketing-Sprech.
Kein Spam. 1-Klick-Abmeldung. Datenschutz bei Loops.so.