Was sind effiziente Möglichkeiten, um mit Datenbankschemata umzugehen, die von Codezweigen gemeinsam genutzt werden?

12

Arbeiten an einem Projekt mit mehreren Zweigen, bei dem jeder Zweig schließlich wieder mit dem Hauptzweig zusammengeführt und im Wesentlichen isoliert wird, um ein neues Feature zu entwickeln.

Die Datenbank, bei der es sich um MS SQL Server handelt, verfügt über ein gemeinsames Schema. Jeder Zweig nimmt jedoch im Verlauf Änderungen am Schema vor.

Meine primäre Frage ist, wie Sie das Schema von der Hauptverzweigung bis zur abgeleiteten Verzweigung gemeinsam nutzen können, damit Änderungen, die an der Hauptverzweigung vorgenommen werden, problemlos in die abgeleitete Verzweigung übernommen werden können, ohne dass neue Änderungen in der abgeleiteten Verzweigung vorgenommen werden müssen Ast?


quelle
2
Nur das Zusammenführen sollte wie jeder andere Code behandelt werden: Automatisches Zusammenführen mit Benutzerinterventions-Fallback und Überprüfung / Testen des Ergebnisses. (Ich bevorzuge die Art und Weise, wie das VS-Datenbankprojekt Schemas mit einem Objekt pro Datei verarbeitet.) Das knifflige Bit kommt mit wie zukunfts Migrationen bestehender Datenbanken arbeiten ;-)
2
Dies hängt stark davon ab, wie Sie das Schema versionieren. Speichern Sie Erstellungsskripte für die Basisobjekte und Änderungsskripte? Verwenden Sie ein Schemavergleichstool, um Änderungsskripts für die Migration zwischen Versionen zu generieren? VS2010 Datenbankprojekte?
Mark Storey-Smith
Relevante Diskussion: dba.stackexchange.com/questions/2/…
Nick Chammas
1
Ebenfalls relevant: martinfowler.com/articles/…
Nick Chammas

Antworten:

7

Ich habe die folgende in der Versionskontrolle und Ihrer Datenbank ausgearbeitete Methode erfolgreich angewendet :

  • Verwalten einer Versionsnummer in Metadaten (Ich verwende eine Datenbank erweiterte Eigenschaft)
  • Jede Schemaänderung wird als Skript codiert, das von der aktuellen Version auf die nächste Version aktualisiert wird
  • Die Anwendung wird mit allen Skripten geliefert, um ein Upgrade von Version 0 (Erstbereitstellung) auf die aktuelle Version durchzuführen
  • Jede Änderung erfolgt über ein Skript. Einschließlich 'System'-Datenänderungen wie Wörterbücher und Nachschlagetabelleneinträge.
  • Bei der Bereitstellung überprüft die Anwendung die Schemaversion auf der Festplatte und führt dann alle Upgrade-Schritte aus, um das Schema auf die aktuell erforderliche Version zu bringen

Ich höre oft die Meinung: "Wie unterscheidet sich das davon, nur die Objektdefinitionsskripte unter Versionskontrolle zu halten?". Der Unterschied ist enorm, da Sie beim Bereitstellen einer neuen Version Ihrer App nicht einfach eine neue Datenbank erstellen. In den meisten Fällen muss Ihre App die vorhandene Datenbank einschließlich der vorhandenen Daten aktualisieren . Dies ist ein entscheidender Unterschied. Ihre Upgrade-Schritte müssen die Integrität und Konsistenz der vorhandenen Daten während des Upgrades sicherstellen. Einige Operationen sind im Code trivial (fügen Sie eine nicht nullfähige Spalte mit dem Standardwert zum Tabellenobjektdefinitionsskript hinzu, erledigt), aber tatsächlich sind sie bei der tatsächlichen Bereitstellung äußerst schmerzhaft (die Tabelle hat 1,5 Milliarden Zeilen, die Spalte add würde ausgehen) von Log-Platz, wenn die "simpleton" Weise getan).

Wie funktioniert das mit der Verzweigung:

  • Wenn die Verzweigung erstellt wird, rastet sie die aktuelle Schemaversion ein, z. B. Version 1.6
  • Wenn das Team mit der Arbeit an dem Zweig beginnt, fügt es eine neue Version 1.7 hinzu und beginnt dann, den Upgrade-Schritt von 1.6 auf 1.7 zu codieren
  • Der Upgradeschritt wird geändert, wenn Änderungen in der Verzweigung vorgenommen werden. Es wird immer das Skript ausgeführt, das ein Upgrade von Version 1.6 auf Version 1.7 durchführt. Was genau diese Skripts jedoch tun, unterliegt den normalen Code-Iterationen und Check-Ins in der Verzweigung
  • Der Zweig beendet die Entwicklung und bereitet sich auf die umgekehrte Integration vor (wird wieder mit der Basislinie zusammengeführt).
    • Es wird eine neue Vorwärtsintegration von der Basislinie zur Verzweigung durchgeführt. Wenn die Integration keine Änderungen an der Schemaversion mit sich bringt, ist alles in Ordnung, und die Verzweigung kann die Integration so wie sie ist rückgängig machen. Version 1.7 wird die neue Basisversion.
    • Das Interessante ist, wenn in der Zwischenzeit eine andere Verzweigung umgekehrt in die Basis integriert wurde und sich nun die Basisschemaversion beispielsweise auf 1.7 geändert hat. In diesem Fall muss unsere Filiale die Version des Bereitstellungszielschemas auf 1.8 erhöhen und den Schritt des Upgrades, der zuvor von 1.6 auf 1.7 erfolgte, überprüfen, um festzustellen, wie es in der neuen Umgebung funktioniert und von 1.7 auf 1.8 aktualisiert wird. Logische Schemakonflikte müssen gelöst werden, das Skript muss möglicherweise geändert werden, und es müssen Tests durchgeführt werden. Nach Abschluss kann der Zweig umgekehrt in die Basis integriert werden. Die bereitgestellte Zielversion des Produkts wird jetzt 1.8.
    • Wenn ein anderer Zweig, der sich in Schema-Version 1.6 verzweigt hat, eine Rückwärtsintegration durchführen möchte, muss er die Schema-Version auf 1.9 erhöhen, das Upgrade-Skript von 1.8 auf 1.9 testen und dann wieder in die Basis integrieren.

Beachten Sie, dass kein Tool, kein Magic Schema Diff Scripting, keine Assistenten und kein Skript zum Generieren von Rechtsklicks erforderlich sind. Dies ist ein zu 100% von Entwicklern gesteuerter Prozess, der auf der Quelle (Skripten) basiert. Viele finden diesen ganzen Prozess aufwendig, aber es funktioniert. Tatsächlich haben Sie als SQL Server-Benutzer die Ergebnisse dieses Prozesses bereits für die tägliche Verwendung von SQL Server genutzt: SQL Server selbst verwendet einen sehr ähnlichen Datenbankaktualisierungsprozess, und wie Sie wahrscheinlich erwarten, wird der Produktentwicklungsprozess umfassend genutzt Verzweigung und das Problem, das Sie erwähnt haben, ist ein sehr reales Problem, das gelöst werden muss.

Übrigens, wie die Verzweigung / Integration tatsächlich abläuft, unterscheidet sich zwischen den Quellcodeverwaltungsprodukten. Ich verwende die aus dem Perforce- Integrate- Betriebsmodus bekannten Begriffe .

Remus Rusanu
quelle
+1, besonders für Jede Änderung wird durch ein Skript durchgeführt
a_horse_with_no_name
1

Meine Antwort ist vielleicht nicht so lang wie die von Remus, aber ich fand, dass dies eine wirklich gute Lösung ist. Ich habe es noch nicht in der Produktion eingerichtet, also YMMV *.

Liquibase

Im Wesentlichen handelt es sich um eine XML-Datei, in der Sie Schemaänderungen an Ihrer Datenbank als neue Elemente in der XML-Datei vornehmen. Beispielsweise:

<createTable tableName="department">
            <column name="id" type="int">
                <constraints primaryKey="true" nullable="false"/>
            </column>

Die Syntax ist vollständig ausgearbeitet, sodass Sie so ziemlich alles tun können, was Sie möchten.

Sie geben in Ihrer Liquibase-Installation auch an, welche Datenbank versioniert werden soll. Anschließend führen Sie die XML-Datei mit der enthaltenen ausführbaren Java-Datei (JAR-Datei) aus. Dadurch werden im Wesentlichen die in der XML angegebenen Änderungen an Ihrer Datenbank neu erstellt.

Der eigentliche Kicker ist, dass Sie diese XML-Datei im selben versionierten Ordner wie Ihren Code speichern. In meinem Fall war das also Git. Ich hatte diese XML-Datei in meinem Projektordner (dieselbe Ebene wie /.git) und wenn ich dann die Verzweigung wechselte, änderte sich die XML-Datei in diese Verzweigungsversion und ich führte die JAR-Datei aus und meine Datenbank spiegelte nun diese Verzweigung wider.

* Hinweis: Ich habe die Implementierung noch nicht abgeschlossen, da ich Probleme hatte, Java mit SQL Server zu verbinden. Benötigt einige JDBC-Treiber und so und ich war nicht in der Stimmung. Daher kann Ihr Kilometerstand variieren.

MikeMurko
quelle
1

Hier bei Red Gate veröffentlichen wir in Kürze eine Datenbankversionslösung, die sowohl SQL Compare als auch SQL Source Control nutzt. Hierbei wird ein Upgrade-Ansatz für Migrationsskripten verwendet, und die Datenbank wird mit einer versionierten Eigenschaft gestempelt, die einer Versionsverwaltungsversion entspricht.

Wir hoffen, Mitte Dezember erscheinen zu können. Derzeit ist ein Release Candidate verfügbar. Für weitere Informationen besuchen Sie:

http://www.red-gate.com/products/sql-development/sql-source-control/entrypage/migration

Wir hoffen, dass wir in den kommenden Monaten auf dieser Lösung aufbauen können. Teilen Sie uns Ihre Meinung mit.

David Atkinson
quelle
0

Wenn Sie und Ihre Schemaänderungen durch Generieren von Skripten und Beibehalten der Quellcodeverwaltung behandelt werden, sollten Sie in der Lage sein, die Änderungen wie bei jeder anderen Codezusammenführung zu behandeln. Sie können auswählen, ob automatisch zusammengeführt oder weitere manuelle Eingriffe vorgenommen werden sollen.


quelle
Nicht wirklich, nein. Das manuelle Zusammenführen von Erstellungsskripten für Basisobjekte ist möglich, aber Änderungen, Referenzdateneinfügungen und Datenbewegungsskripten werden sehr schnell und unübersichtlich.
Mark Storey-Smith
Einverstanden. Hier bei Red Gate glauben wir, dass Erstellungsskripte ziemlich gut zusammenlaufen und automatisiert werden könnten. Die Migrationsskripte zwischen den Versionen müssen jedoch manuell zusammengeführt werden, um eine falsche Reihenfolge der Abhängigkeiten und eine Duplizierung des Änderungscodes zu vermeiden.
David Atkinson
0

Ich bin in einer ähnlichen Situation, in der ich an einer Live-Website und mehreren Entwicklungszweigen arbeite, in denen ich das Datenbankschema ändern muss.

Ich habe es gelöst, indem ich einen Post-Checkout und einen Post-Merge-Hook geschrieben habe, die gut mit git verwendet werden können. Ich speichere alle meine Migrationen in Form von SQL-Dateien in einem separaten Verzeichnis und übergebe sie zusammen mit dem geänderten PHP-Code. Jedes Mal, wenn ich eine

git checkout

oder ein

git merge

git ruft automatisch die entsprechenden Up- und Down-Migrationen auf. Siehe meine Implementierung auf Github .

Richard Brinkman
quelle