[Php] Mechanismen zum Verfolgen von Datenbankschemaänderungen


Answers

Wir verwenden etwas Ähnliches wie bcwoord, um unsere Datenbankschemata in 5 verschiedenen Installationen (Produktion, Staging und einige Entwicklungsinstallationen) zu synchronisieren und in der Versionskontrolle zu sichern, und es funktioniert ziemlich gut. Ich werde ein wenig ausarbeiten:

Um die Datenbankstruktur zu synchronisieren, haben wir ein einzelnes Skript, update.php, und eine Anzahl von Dateien mit den Nummern 1.sql, 2.sql, 3.sql, etc. Das Skript verwendet eine zusätzliche Tabelle, um die aktuelle Versionsnummer des Datenbank. Die N.SQL-Dateien werden von Hand erstellt, um von Version (N-1) zu Version N der Datenbank zu wechseln.

Sie können verwendet werden, um Tabellen hinzuzufügen, Spalten hinzuzufügen, Daten von einem alten in ein neues Spaltenformat zu migrieren, dann die Spalte zu löschen, "Master" -Datenzeilen wie Benutzertypen usw. einzufügen. Grundsätzlich kann es alles und mit geeigneten Daten tun Migrationsskripten verlieren Sie nie Daten.

Das Update-Skript funktioniert so:

  • Stellen Sie eine Verbindung zur Datenbank her.
  • Erstellen Sie eine Sicherungskopie der aktuellen Datenbank (weil die Dinge schief gehen) [mysqldump].
  • Erstellen Sie eine Buchhaltungstabelle (namens _meta), wenn sie nicht existiert.
  • Lesen Sie die aktuelle VERSION aus der Tabelle _meta. Nehme 0 an, wenn nicht gefunden.
  • Für alle .sql-Dateien, die höher nummeriert sind als VERSION, führen Sie sie der Reihe nach durch
  • Wenn eine der Dateien einen Fehler verursacht hat, führen Sie einen Rollback zur Sicherung durch
  • Aktualisieren Sie andernfalls die Version in der Buchhaltungstabelle mit der höchsten ausgeführten .sql-Datei.

Alles geht in die Quellcodeverwaltung und jede Installation hat ein Skript, um mit einer einzigen Skriptausführung auf die neueste Version zu aktualisieren (Aufruf von update.php mit dem richtigen Datenbankpasswort usw.). Wir SVN aktualisieren Staging- und Produktionsumgebungen über ein Skript, das automatisch das Datenbankaktualisierungsskript aufruft, sodass ein Code-Update mit den erforderlichen Datenbank-Updates geliefert wird.

Wir können auch dasselbe Skript verwenden, um die gesamte Datenbank von Grund auf neu zu erstellen. Wir löschen und erstellen die Datenbank neu und führen dann das Skript aus, das die Datenbank vollständig neu auffüllt. Wir können das Skript auch verwenden, um eine leere Datenbank für das automatisierte Testen aufzufüllen.

Es dauerte nur ein paar Stunden, um dieses System einzurichten, es ist konzeptionell einfach und jeder erhält das Versionsnummerierungsschema und es war von unschätzbarem Wert, um das Datenbankdesign weiterzuentwickeln, ohne die Änderungen kommunizieren oder manuell ausführen zu müssen auf allen Datenbanken.

Vorsicht beim Einfügen von Anfragen von phpMyAdmin! Diese generierten Abfragen enthalten normalerweise den Datenbanknamen, den Sie definitiv nicht haben wollen, da er Ihre Skripte unterbricht! Etwas wie CREATE TABLE mydb . newtable (...) newtable fehl, wenn die Datenbank auf dem System nicht myDB heißt. Wir haben einen SVN-Hook vorkommentar erstellt, der sql-Dateien verbietet, die die mydb Zeichenkette enthalten, was ein sicheres Zeichen dafür ist, dass jemand von phpMyAdmin kopiert oder eingefügt wurde, ohne die entsprechende Prüfung mydb .

Question

Was sind die besten Methoden zum Verfolgen und / oder Automatisieren von DB-Schemaänderungen? Unser Team verwendet Subversion für die Versionskontrolle und wir konnten einige unserer Aufgaben auf diese Weise automatisieren (Push-Builds auf einen Staging-Server, Bereitstellung von getestetem Code auf einem Produktionsserver), aber wir führen immer noch Datenbankupdates manuell durch. Ich möchte eine Lösung finden oder erstellen, die es uns ermöglicht, effizient auf Servern mit unterschiedlichen Umgebungen zu arbeiten, während wir weiterhin Subversion als Backend verwenden, über das Code- und DB-Updates auf verschiedene Server verteilt werden.

Viele populäre Software-Pakete enthalten Auto-Update-Skripte, die die DB-Version erkennen und die notwendigen Änderungen vornehmen. Ist dies der beste Weg, dies auch in einem größeren Maßstab (über mehrere Projekte und manchmal mehrere Umgebungen und Sprachen) zu tun? Wenn ja, gibt es einen vorhandenen Code, der den Prozess vereinfacht, oder ist es am besten, eine eigene Lösung zu erstellen? Hat jemand schon etwas Ähnliches implementiert und es in Subversion Post-Commit Hooks integriert, oder ist das eine schlechte Idee?

Während eine Lösung, die mehrere Plattformen unterstützt, vorzuziehen ist, müssen wir auf jeden Fall den Linux / Apache / MySQL / PHP-Stack unterstützen, da der Großteil unserer Arbeit auf dieser Plattform stattfindet.




Für mein aktuelles PHP-Projekt verwenden wir die Idee von Rails-Migrationen und wir haben ein Migrationsverzeichnis, in dem wir den Titel "migration_XX.sql" behalten, wobei XX die Nummer der Migration ist. Derzeit werden diese Dateien von Hand erstellt, wenn Aktualisierungen vorgenommen werden, aber ihre Erstellung könnte leicht geändert werden.

Dann haben wir ein Skript namens "Migration_watcher", das, wie wir in pre-alpha sind, derzeit bei jedem Laden der Seite ausgeführt wird und überprüft, ob es eine neue migration_XX.sql-Datei gibt, in der XX größer ist als die aktuelle Migrationsversion. Wenn dies der Fall ist, werden alle migration_XX.sql-Dateien bis zur höchsten Anzahl gegen die Datenbank ausgeführt, und voila! Schemaänderungen sind automatisiert.

Wenn Sie die Möglichkeit benötigen, das System zurückzusetzen, wären viele Feinabstimmungen erforderlich, aber es ist einfach und hat bisher für unser relativ kleines Team sehr gut funktioniert.




Es ist ein bisschen Low-Tech, und es könnte eine bessere Lösung da draußen sein, aber Sie könnten Ihr Schema einfach in einem SQL-Skript speichern, das ausgeführt werden kann, um die Datenbank zu erstellen. Ich denke, Sie können einen Befehl ausführen, um dieses Skript zu generieren, aber ich kenne den Befehl leider nicht.

Übergeben Sie dann das Skript zusammen mit dem Code, der darauf ausgeführt wird, in die Quellcodeverwaltung. Wenn Sie das Schema zusammen mit dem Code ändern müssen, kann das Skript zusammen mit dem Code, der das geänderte Schema erfordert, eingecheckt werden. Dann zeigen Diffs im Skript Diffs bei Schemaänderungen an.

Mit diesem Skript können Sie es in DBUnit oder eine Art Build-Skript integrieren, so dass es zu Ihren bereits automatisierten Prozessen passt.




Toad for MySQL hat eine Funktion namens schema compare, mit der Sie 2 Datenbanken synchronisieren können. Es ist das beste Werkzeug, das ich bisher benutzt habe.







Das Problem hier macht es wirklich einfach für Entwickler, ihre eigenen lokalen Änderungen in die Quellcodeverwaltung zu schreiben, um sie mit dem Team zu teilen. Ich bin seit vielen Jahren mit diesem Problem konfrontiert und habe mich von den Funktionen von Visual Studio für Datenbankprofis inspirieren lassen. Wenn Sie ein Open-Source-Tool mit den gleichen Funktionen möchten, versuchen Sie http://dbsourcetools.codeplex.com/ : http://dbsourcetools.codeplex.com/ Viel Spaß, - Nathan.




Es gibt ein Befehlszeilenprogramm mysql-diff , das Datenbankschemas vergleicht, wobei Schema eine Live-Datenbank oder ein SQL-Skript auf der Festplatte sein kann. Es ist für die meisten Schemamigrationsaufgaben geeignet.




Speichern Sie Ihr Schema in einer Datei und fügen Sie es der Quellcodeverwaltung hinzu. Dann zeigt dir ein einfacher Vergleich, was sich geändert hat.




Wir verwenden eine sehr einfache, aber dennoch effektive Lösung.

Für neue Installationen haben wir eine metadata.sql-Datei im Repository, die das gesamte DB-Schema enthält, und dann verwenden wir diese Datei im Build-Prozess, um die Datenbank zu generieren.

Für Updates fügen wir die Updates in die Hardcoded-Software ein. Wir halten es fest codiert, weil wir Probleme nicht gerne lösen, bevor es wirklich ein Problem ist, und diese Art von Sache erwies sich bisher als kein Problem.

In unserer Software haben wir so etwas:

RegisterUpgrade(1, 'ALTER TABLE XX ADD XY CHAR(1) NOT NULL;');

Dieser Code überprüft, ob sich die Datenbank in Version 1 befindet (die in einer automatisch erstellten Tabelle gespeichert ist). Wenn sie veraltet ist, wird der Befehl ausgeführt.

Um die metadata.sql im Repository zu aktualisieren, führen wir diese Upgrades lokal aus und extrahieren dann die vollständigen Metadaten der Datenbank.

Das einzige, was immer wieder passiert, ist, die metadata.sql zu vergessen, aber das ist kein großes Problem, da es einfach ist, den Build-Prozess zu testen, und das einzige, was passieren könnte, ist eine neue Installation mit eine veraltete Datenbank und aktualisiert es bei der ersten Verwendung.

Wir unterstützen auch keine Downgrades, aber es ist von Entwurf, wenn bei einem Update etwas kaputt geht, haben wir die vorherige Version wiederhergestellt und das Update repariert, bevor wir es erneut versuchen.




Ich mag die Art und Weise, wie Yii Datenbankmigrationen behandelt. Eine Migration ist im Grunde ein PHP-Skript, das CDbMigration implementiert. CDbMigration definiert eine up Methode, die die Migrationslogik enthält. Es ist auch möglich, eine down Methode zu implementieren, um die Umkehrung der Migration zu unterstützen. Alternativ kann safeUp oder safeDown verwendet werden, um sicherzustellen, dass die Migration im Kontext einer Transaktion erfolgt.

Yiis Kommandozeilen-Tool yiic enthält Unterstützung zum Erstellen und Ausführen von Migrationen. Migrationen können entweder einzeln oder in einem Batch angewendet oder rückgängig gemacht werden. Durch die Erstellung einer Migration wird Code für eine PHP-Klasse CDbMigration , die CDbMigration implementiert und basierend auf einem Zeitstempel und einem vom Benutzer angegebenen Migrationsnamen einen eindeutigen Namen CDbMigration . Alle Migrationen, die zuvor auf die Datenbank angewendet wurden, werden in einer Migrationstabelle gespeichert.

Weitere Informationen finden Sie im Artikel zur Datenbankmigration im Handbuch.