Historie des Themas
Die Arbeit an großen Projekten erfordert, dass sich die Struktur der Datenbank parallel zum Anwendungscode entwickelt. Ohne versionskontrollierte Änderungen an der Schema (Hinzufügung, Löschung und Änderung von Tabellen, Indizes, Schlüsseln) verliert das Team schnell den Synchronisationsstatus, das Risiko, Änderungen zu verlieren, wird erhöht, Migrationen können fehlschlagen und das Zurücksetzen oder die Reproduktion von Bugs wird komplexer.
Problem
Der traditionelle Ansatz – manuelle Änderungen an der DB über SQL-Skripte – führt zu einer nicht expliziten Reihenfolge der Änderungen, Schwierigkeiten beim Zurücksetzen und Versioninkongruenzen zwischen den Umgebungen (dev, test, prod). Ohne ein gemeinsames Werkzeug zur Speicherung von Migrationen ist es schwierig, zu verstehen, wer, wann und warum das Schema geändert hat.
Lösung
Für diese Aufgabe werden Schemastrukturmigrationen und Praktiken der Datenbankversionierung verwendet. Der Einsatz von Werkzeugen (z.B. Liquibase, Flyway, Alembic für verschiedene DBMS) ermöglicht es, SQL-Skripte für Schemaänderungen direkt im Versionskontrollsystem (git) zu speichern, eine strenge Reihenfolge von Migrationen zu bilden und Schemaaktualisierungen in allen Umgebungen zu automatisieren.
Beispielcode (Migration über Flyway):
-- V002__add_column_email.sql ALTER TABLE users ADD COLUMN email VARCHAR(255) NOT NULL;
Integration von Flyway (z.B. für Java):
Flyway.configure().dataSource(url, user, pass).load().migrate();
Wesentliche Merkmale:
Kann man den "ursprünglichen Zustand" des Schemas (Snapshot) anstelle von Migrationen speichern? Auf den ersten Blick ist ein „Dump“ des gesamten Schemas einfacher als Migrationen. Aber dann entstehen Probleme beim Zurücksetzen, der Wiederherstellung von Zwischenzuständen und beim Zusammenführen von Änderungen aus verschiedenen Branches. Migrationen ermöglichen die Anwendung nur neuer Änderungen in der richtigen Reihenfolge und nacheinander.
Muss man Migrationen manuell zwischen verschiedenen Umgebungen synchronisieren? Nein, moderne Systeme respektieren die Versionierung und wenden nur die Migrationen an, die noch nicht in der Datenbank waren. Das Wichtige ist nicht die manuelle Synchronisation, sondern die automatisierte Anwendung von Migrationen beim Deployment.
Reichen nur SQL-Skripte für Migrationen oder sollte man noch etwas anderes speichern? Eine gute Praxis ist es, neben SQL-Skripten auch deren Beschreibung (Zweck, Autor, Datum) sowie Testvalidierungen für neue strukturelle Änderungen zu speichern, um die Qualität von Migrationen automatisiert zu kontrollieren.
Das Projekt verwendete gewöhnliche Dumps des Schemas und "manuelle" Anwendung von Änderungen durch die Entwickler. Nach dem Start des Updates bemerkte der Kunde, dass einige neue Spalten in der Produktionsdatenbank nicht erschienen, während sich einige Indizes nach jedem Versuch, das Schema zu aktualisieren, verdoppten.
Vorteile:
Schnell für sehr kleine Projekte.
Nachteile:
Schwierigkeiten bei der Wartung; es kann nicht verstanden werden, was genau geändert wurde und von wem; es gibt keine Möglichkeit zurückzusetzen; verschiedene Umgebungen drifteten auseinander.
Das Team hat Flyway integriert, alle strukturellen Änderungen erfolgen durch Migrationen mit Code-Reviews, das Zurücksetzen beliebiger Versionen dauerte nur wenige Minuten, Tests und Kontrollen waren einfach auf allen Umgebungen durchzuführen.
Vorteile:
Automatisierung, Historie, geringe Wahrscheinlichkeit von Bugs beim Deployment.
Nachteile:
Es muss etwas länger dokumentiert werden, um jede Strukturänderung zu beschreiben.