Cloud allgemein

Schema Evolution: Delta Lake, Iceberg und Avro im Vergleich

Schema-Evolution-Strategien für Delta Lake, Apache Iceberg und Avro: Wie du Schema-Änderungen ohne manuelle Eingriffe und Datenverlust managest.

Harbinger Team14. Mai 20267 Min. LesezeitAktualisiert 14.5.2026
  • schema evolution
  • delta lake
  • apache iceberg
  • avro
  • data engineering
  • schema changes
  • data formats
  • dach
Inhaltsverzeichnis19 Abschnitte

Schema Evolution für Delta Lake, Iceberg und Avro

Ein Source-Team benennt eine Spalte von user_id zu userId am Freitagnachmittag um. Am Montag liefert deine Pipeline Nulls für 40% der Zeilen, drei Dashboards sind kaputt und niemand hat ein Ticket aufgemacht. Schema-Änderungen sind der stille Killer von Daten-Pipelines.

Schema Evolution ist die Menge an Strategien, die deine Datensysteme diese Änderungen elegant absorbieren lassen — ohne manuelle Eingriffe, Datenverlust oder 2-Uhr-Pages.

TL;DR

  • Delta Lake: mergeSchema für additive Changes, Column-Mapping für Renames
  • Iceberg: Column-IDs entkoppeln Namen von Speicherung — Renames sind metadata-only
  • Avro: Schema-Registry mit Compatibility-Modes (BACKWARD am häufigsten)

Warum Schema Evolution schwer ist

Datenformate für analytischen Storage (Parquet, ORC) tragen kein Schema-Metadata auf File-Ebene — das Schema wird zur Read-Time inferiert. Wenn das Schema sich ändert, produzieren Reader, die nicht aktualisiert wurden, falsche Ergebnisse oder schweigen.

Moderne Table-Formate (Delta Lake, Apache Iceberg) und Serialisierungs-Frameworks (Avro, Protobuf) gehen das Problem unterschiedlich an. Ihre Modelle zu verstehen hilft, das richtige Tool pro Szenario zu wählen.

Die vier Typen von Schema-Änderungen

Change-TypRisikoKompatibel?
Nullable Spalte hinzufügenNiedrigBackward-kompatibel
Non-Nullable Spalte hinzufügenHochBreaking
Spalte entfernenMittelBackward-kompatibel (wenn Reader Unbekanntes ignorieren)
Spalte umbenennenHochBreaking (logisch Drop + Add)
Typ erweitern (int zu long)Niedrig-MittelMeist sicher
Typ verengen (long zu int)HochBreaking — Datenverlust-Risiko
Typ ändern (string zu int)HochBreaking

Die zentrale Frage bei jeder Schema-Änderung: welche Seite ist die Beschränkung — Writer oder Reader?

Schema Evolution in Delta Lake

Delta Lake speichert das Tabellen-Schema im Transaction-Log. Jeder Write muss dem aktuellen Schema entsprechen — der "Schema-Enforcement"-Mode. Schema Evolution braucht explizites Opt-in.

Automatisches Schema-Merging

# PySpark — Delta Lake Schema-Merge beim Write
from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("schema_evolution") \
    .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") \
    .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog") \
    .getOrCreate()

# Neuer DataFrame mit extra Spalte: 'country'
new_data = spark.createDataFrame([
    ("u001", "Alice", "DE"),
    ("u002", "Bob", "US"),
], ["user_id", "name", "country"])

# mergeSchema=True fügt neue Spalte zum Tabellen-Schema hinzu
new_data.write \
    .format("delta") \
    .mode("append") \
    .option("mergeSchema", "true") \
    .save("/delta/users")

Mit mergeSchema=True fügt Delta Lake die neue country-Spalte zum Schema hinzu. Bestehende Zeilen liefern NULL für country. Sicher für additive Changes.

Schema überschreiben

Für destruktive Changes (Spalten reordern, Typen ändern) overwriteSchema nutzen:

# Delta Lake — gesamtes Schema überschreiben
# WARNUNG: schreibt Schema um; bestehende Daten werden mit neuer Definition gelesen
new_data.write \
    .format("delta") \
    .mode("overwrite") \
    .option("overwriteSchema", "true") \
    .save("/delta/users")

overwriteSchema ist destruktiv — nur nutzen, wenn du das Schema absichtlich ersetzen willst.

Column Mapping (DV 2.0+)

Delta Lakes Column-Mapping (Delta 2.0+) ermöglicht physisches Umbenennen ohne File-Rewrite:

-- Spark SQL (Delta Lake) — Spalte ohne File-Rewrite umbenennen
ALTER TABLE users SET TBLPROPERTIES (
    'delta.columnMapping.mode' = 'name',
    'delta.minReaderVersion' = '2',
    'delta.minWriterVersion' = '5'
);

ALTER TABLE users RENAME COLUMN user_id TO userId;

Column-Mapping speichert ein physical-zu-logical Name-Mapping im Delta-Log. Alte Files sind weiter valide — nur Metadata ändert sich. Das ist der richtige Weg, um Spalten in Delta Lake umzubenennen.

Schema Evolution in Apache Iceberg

Iceberg wurde mit Schema Evolution als First-Class-Feature designed. Sein Metadata-Modell trackt Column-IDs separat von Namen — der fundamentale Unterschied zu Delta Lake.

Icebergs Column-ID-Modell

In Iceberg hat jede Spalte eine stabile Integer-ID bei Erstellung. Wenn du eine Spalte umbenennst, änderst du den Namen — aber die ID (die auf physische File-Daten mappt) bleibt. Reader, die Column-IDs nutzen (Default), sehen das Rename transparent.

-- Iceberg SQL (Spark SQL Dialekt mit Iceberg-Catalog)

-- Spalte hinzufügen
ALTER TABLE catalog.db.users ADD COLUMN (country STRING);

-- Spalte umbenennen — sicher, kein Data-Rewrite
ALTER TABLE catalog.db.users RENAME COLUMN user_id TO userId;

-- Spalte droppen
ALTER TABLE catalog.db.users DROP COLUMN legacy_phone;

-- Typ erweitern (int zu bigint) — sicher
ALTER TABLE catalog.db.users ALTER COLUMN age TYPE bigint;

All diese Operationen sind in Iceberg metadata-only — keine Data-Files werden umgeschrieben.

Iceberg Schema-Evolution-Regeln

OperationData-Rewrite?Sicher?
Spalte hinzufügenNeinJa
Spalte droppenNeinJa (bestehende Files behalten Spalte, Reader ignorieren)
Spalte umbenennenNeinJa (ID-basiertes Tracking)
Spalten reordernNeinJa
Typ erweitern (int zu long, float zu double)NeinJa
Typ verengen (long zu int)NeinTechnisch erlaubt, Datenverlust-Risiko
Typ ändern (string zu int)NeinSchlägt zur Read-Zeit fehl, wenn Werte inkompatibel

Iceberg ist permissiver als Delta Lake bei Column-Operationen, mit Column-ID-Tracking, das Renames genuin sicher macht.

Schema Evolution in Avro

Avro nutzt JSON-definierte Schemas, in oder neben Data-Files. Gebaut für Streaming (Kafka) und RPC, wo Producer- und Consumer-Schemas zu jedem Zeitpunkt unterscheidlich sein können.

Avro-Compatibility-Modes

Avro definiert drei Compatibility-Modes, enforced durch eine Schema Registry (Confluent Schema Registry ist Standard):

# Python — Avro Schema-Evolution-Beispiel
import json

# V1 Schema
schema_v1 = {
    "type": "record",
    "name": "User",
    "fields": [
        {"name": "user_id", "type": "string"},
        {"name": "name",    "type": "string"}
    ]
}

# V2 Schema — fügt optionales Feld mit Default hinzu (BACKWARD-kompatibel)
schema_v2 = {
    "type": "record",
    "name": "User",
    "fields": [
        {"name": "user_id", "type": "string"},
        {"name": "name",    "type": "string"},
        # Neues Feld MUSS Default haben für Backward-Compat
        {"name": "country", "type": ["null", "string"], "default": None}
    ]
}

# V2 kann V1-Daten lesen (country -> null für alte Records): BACKWARD-kompatibel
# V1 kann V2-Daten nicht lesen (unbekanntes Feld 'country'): NICHT FORWARD-kompatibel

Avro-Compatibility-Matrix

ModeNeues Schema liest alte Daten?Altes Schema liest neue Daten?
BACKWARDJaNein
FORWARDNeinJa
FULLJaJa
NONESchema-Registry erzwingt nichts

Regeln für BACKWARD-Compatibility (häufigster Mode):

  • Feld hinzufügen: muss Default haben
  • Feld entfernen: nur Felder mit Default
  • Feld umbenennen: aliases nutzen (kein Rename — neues Feld mit Alias)
  • Typ ändern: generell nicht erlaubt
{
  "type": "record",
  "name": "User",
  "fields": [
    {
      "name": "userId",
      "type": "string",
      "aliases": ["user_id"]
    }
  ]
}

Das aliases-Feld sagt Avro-Readern: "wenn du in alten Daten ein Feld namens user_id triffst, mappe es auf userId." So benennst du Felder ohne Backward-Compat zu brechen.

Die richtige Strategie wählen

SzenarioEmpfehlung
Lakehouse mit Batch-Pipelines, Databricks/SparkDelta Lake + Column-Mapping für Renames
Lakehouse mit echten Column-Renames + Type-EvolutionApache Iceberg
Kafka-Streaming mit Producer/Consumer-Schema-UnabhängigkeitAvro + Confluent Schema Registry (BACKWARD)
Mehrere Schema-Versionen parallelIceberg + Time-Travel; Avro + Schema-Registry-Versionen
Unbekannte zukünftige Schema-Changes aus externen QuellenContract-basiert: Data Contracts

Häufige Fehler

1. Column-Renames mit Drop+Add verwechseln. In Plain-Parquet (kein Table-Format) heißt Rename: Daten der alten Spalte sind weg. In Iceberg und Delta Lake mit Column-Mapping ist es metadata-only. Wisse, auf welcher Schicht du operierst.

2. Non-Nullable Avro-Felder ohne Default hinzufügen. Bricht BACKWARD-Compat sofort. Immer nullable Union-Types ["null", "string"] mit "default": null für neue Avro-Felder.

3. Type-Widening-Limits ignorieren. int -> long ist sicher. float -> double ist sicher. string -> int ist nie sicher, auch wenn Werte heute numerisch sind — ein malformed Wert bricht deine Pipeline.

4. Schema-Changes ohne Versionierung. Jede Schema-Änderung sollte durch Versionskontrolle (dbt-Model-Diffs, Avro-Schema-Registry). "Quick-Fix"-Changes direkt in Production ohne Tracking sind die Hauptursache der meisten Schema-Incidents.

Schema-Change-Checkliste

Vor jeder Schema-Änderung in Production:

  • Change-Typ klassifizieren (add/remove/rename/type)
  • Alle Downstream-Consumer identifizieren (Pipelines, Dashboards, ML-Modelle)
  • Backward/Forward-Compat mit gewähltem Format testen
  • Downstream-Owner vor Deploy informieren
  • Column-Mapping (Delta) oder Column-IDs (Iceberg) für Renames statt Drop+Add
  • Schema-Migration-Eintrag in Datenkatalog oder Change-Log

FAQ

Wann Delta Lake, wann Iceberg? Wenn du tief in Databricks/Spark steckst: Delta. Bei Multi-Engine-Lakehouse (Trino, Snowflake, Spark) oder echten Cross-Engine-Renames: Iceberg.

Funktioniert Avro auch außerhalb von Kafka? Ja, Avro ist generelles Serialisierungsformat. Mit Kafka am häufigsten, aber auch in Hadoop-Ökosystem und RPC-Frameworks.

Wie tracke ich Schema-Changes in einer Pipeline? Schema-Snapshots in Git committen (dbt-Models, Avro-Files). Pre-Deploy-Check via Schema-Registry oder Compatibility-Test in CI.

Was bei externen API-Schemas? Tools wie Harbinger Explorer crawlen APIs und tracken Schema-Diffs zwischen Crawls — du siehst Drift, bevor sie Pipelines bricht.

Spielt das für DACH-Compliance eine Rolle? Schema-Tracking ist Teil ordentlicher Daten-Dokumentation, die DSGVO Artikel 30 indirekt verlangt (Verzeichnis der Verarbeitungstätigkeiten).

Fazit

Schema Evolution ist keine theoretische Sorge — wöchentliche Realität für jedes Team mit Production-Pipelines. Delta Lake und Iceberg handhaben additive Changes elegant und machen Renames metadata-sicher. Avros Schema-Registry gibt Kafka-Pipelines die Compat-Garantien für unabhängige Producer/Consumer-Deployments.

Die schlimmsten Schema-Migrations passieren, wenn Teams keine Strategie haben. Die besten sind unsichtbar für Downstream-Consumer.

Nächster Schritt: Schema-Evolution mit formalem Change-Process kombinieren — Data Contracts für Teams.

Weiterlesen

Stand: 14. Mai 2026.

H

Geschrieben von

Harbinger Team

Cloud-, Data- und AI-Engineer in DACH. Schreibt seit 2018 über infrastruktur­kritische 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.