Im SO-Community-Wiki wurde diskutiert, ob Datenbankobjekte versioniert werden sollten. Allerdings habe ich nicht für die Erstellung eines Build-Automatisierungsprozess für Datenbankobjekte viel Diskussion über die besten Praktiken gesehen.
Dies war ein umstrittener Diskussionspunkt für mein Team - insbesondere, da Entwickler und Datenbankadministratoren bei der Bewertung der Vorteile und Risiken eines Automatisierungsansatzes für die Datenbankbereitstellung häufig unterschiedliche Ziele, Ansätze und Bedenken verfolgen.
Ich würde gerne einige Ideen von der SO-Community hören, welche Praktiken in der realen Welt effektiv waren.
Mir ist klar, dass es etwas subjektiv ist, welche Praktiken wirklich am besten sind, aber ich denke, ein guter Dialog darüber, welche Arbeit für viele Leute hilfreich sein könnte.
Hier sind einige meiner Teaser-Fragen zu Problembereichen in diesem Thema. Diese sind nicht als endgültige Liste gedacht, sondern als Ausgangspunkt, damit die Leute verstehen, wonach ich suche.
- Sollten sowohl Test- als auch Produktionsumgebungen aus der Quellcodeverwaltung erstellt werden?
- Sollten beide mithilfe von Automatisierung erstellt werden - oder sollte die Produktion durch Kopieren von Objekten aus einer stabilen, endgültigen Testumgebung erstellt werden?
- Wie gehen Sie mit potenziellen Unterschieden zwischen Test- und Produktionsumgebungen in Bereitstellungsskripten um?
- Wie testen Sie, ob die Bereitstellungsskripte genauso effektiv gegen die Produktion funktionieren wie im Test?
- Welche Arten von Objekten sollten versioniert werden?
- Nur Code (Prozeduren, Pakete, Trigger, Java usw.)?
- Indizes?
- Einschränkungen?
- Tabellendefinitionen?
- Tabellenänderungsskripte? (zB ALTER-Skripte)
- Alles?
- Welche Objekttypen sollten nicht versioniert werden?
- Sequenzen?
- Zuschüsse?
- Benutzerkonten?
- Wie sollten Datenbankobjekte in Ihrem SCM-Repository organisiert sein?
- Wie gehen Sie mit einmaligen Dingen wie Konvertierungsskripten oder ALTER-Skripten um?
- Wie gehen Sie mit dem Löschen von Objekten aus der Datenbank um?
- Wer sollte für die Förderung von Objekten von der Entwicklung bis zum Test verantwortlich sein?
- Wie koordinieren Sie Änderungen von mehreren Entwicklern?
- Wie gehen Sie mit der Verzweigung von Datenbankobjekten um, die von mehreren Systemen verwendet werden?
- Welche Ausnahmen, wenn überhaupt, können für diesen Prozess angemessen sein?
- Sicherheitsprobleme?
- Daten mit Bedenken hinsichtlich der Identifizierung?
- Skripte, die nicht vollständig automatisiert werden können?
- Wie können Sie den Prozess belastbar und durchsetzbar machen?
- Zum Entwicklerfehler?
- Zu unerwarteten Umweltproblemen?
- Für die Notfallwiederherstellung?
- Wie können Sie Entscheidungsträger davon überzeugen, dass die Vorteile von DB-SCM die Kosten wirklich rechtfertigen?
- Anekdoten?
- Industrieforschung?
- Best-Practice-Empfehlungen der Branche?
- Appelle an anerkannte Behörden?
- Kosten-Nutzen-Analyse?
- Wem sollten Datenbankobjekte in diesem Modell "gehören"?
- Entwickler?
- Datenbankadministratoren?
- Datenanalysten?
- Mehr als eine?
quelle
Antworten:
Hier einige Antworten auf Ihre Fragen:
quelle
Ich behandle das SQL wenn möglich als Quellcode
Wenn ich es in standardkonformem SQL schreiben kann, wird es im Allgemeinen in einer Datei in meiner Quellcodeverwaltung gespeichert. Die Datei definiert so viel wie möglich, z. B. SPs, Table CREATE-Anweisungen.
Ich füge auch Dummy-Daten zum Testen in die Quellcodeverwaltung ein:
Und dann abstrahiere ich alle meine SQL-Abfragen, damit ich das gesamte Projekt für MySQL, Oracle, MSSQL oder irgendetwas anderes erstellen kann.
Die Build- und Testautomatisierung verwendet diese Build-Skripte, da sie genauso wichtig sind wie die App-Quelle und testet alles von der Integrität über Trigger, Prozeduren und Protokollierung.
quelle
Wir nutzen die kontinuierliche Integration über TeamCity. Bei jedem Einchecken in die Quellcodeverwaltung werden die Datenbank und alle Testdaten von Grund auf neu erstellt, dann der Code und anschließend die Komponententests für den Code ausgeführt. Wenn Sie ein Codegenerierungstool wie CodeSmith verwenden, kann es auch in Ihren Erstellungsprozess eingefügt werden, um Ihre Datenzugriffsschicht bei jedem Build neu zu generieren. So stellen Sie sicher, dass alle Ihre Schichten "übereinstimmen" und keine Fehler aufgrund von erzeugen Nicht übereinstimmende SP-Parameter oder fehlende Spalten.
Jeder Build verfügt über eine eigene Sammlung von SQL-Skripten, die im Verzeichnis $ project \ SQL \ in der Quellcodeverwaltung gespeichert, mit einem numerischen Präfix versehen und der Reihe nach ausgeführt werden. Auf diese Weise üben wir unser Bereitstellungsverfahren bei jedem Build.
Abhängig von der Nachschlagetabelle werden die meisten unserer Nachschlagewerte auch in Skripten gespeichert und ausgeführt, um sicherzustellen, dass die Konfigurationsdaten den Erwartungen entsprechen, z. B. "reason_codes" oder "country_codes". Auf diese Weise können wir eine Änderung der Suchdaten in dev vornehmen, sie testen und dann durch Qualitätssicherung und Produktion "fördern", anstatt ein Tool zum Ändern der Suchwerte in der Produktion zu verwenden, was für die Betriebszeit gefährlich sein kann.
Wir erstellen auch eine Reihe von "Rollback" -Skripten, die unsere Datenbankänderungen rückgängig machen, falls ein Build für die Produktion schief geht. Sie können die Rollback-Skripte testen, indem Sie sie ausführen und anschließend die Komponententests für die Build-One-Version unter Ihrer erneut ausführen, nachdem die Bereitstellungsskripts ausgeführt wurden.
quelle
+1 für Liquibase : LiquiBase ist eine datenbankunabhängige Open Source (LGPL) -Bibliothek zum Verfolgen, Verwalten und Anwenden von Datenbankänderungen. Es basiert auf einer einfachen Prämisse: Alle Datenbankänderungen (Struktur und Daten) werden in einer XML-basierten beschreibenden Weise gespeichert und in die Quellcodeverwaltung eingecheckt. Der gute Punkt ist, dass DML-Änderungen nicht nur diff, sondern semantisch gespeichert werden, damit Sie den Zweck der Änderungen verfolgen können.
Es könnte zur besseren Interaktion mit der GIT- Versionskontrolle kombiniert werden . Ich werde unsere Dev-Prod-Umgebung so konfigurieren, dass sie es ausprobiert.
Sie können auch Maven, Ant- Build-Systeme zum Erstellen von Produktionscode aus Skripten verwenden.
Das Minus ist, dass LiquiBase nicht in weit verbreitete SQL-IDEs integriert ist und Sie grundlegende Operationen selbst ausführen sollten.
Darüber hinaus können Sie DBUnit für DB-Tests verwenden. Mit diesem Tool können Datengenerierungsskripts zum Testen Ihrer Produktionsumgebung mit anschließender Bereinigung verwendet werden.
MEINER BESCHEIDENEN MEINUNG NACH:
Wir hatten alle genannten Probleme mit Codeänderungen, Zusammenführen und Umschreiben in unserer Abrechnungsproduktionsdatenbank. Dieses Thema ist großartig, um all diese Dinge zu entdecken.
quelle
Wenn Sie "Teaser-Fragen" stellen, scheinen Sie mehr an einer Diskussion interessiert zu sein als an der Meinung einer Person zu endgültigen Antworten. Die aktive Mailingliste agileDatabases (> 2500 Mitglieder) hat viele dieser Fragen beantwortet und ist meiner Erfahrung nach ein anspruchsvolles und ziviles Forum für diese Art von Diskussion.
quelle
Grundsätzlich stimme ich jeder Antwort von van zu . Für weitere Einblicke ist meine Basis für das Datenbankmanagement die K. Scott Allen-Serie (ein Muss, IMHO. Und Jeffs Meinung scheint es auch).
Create.sql
. Dies kann das Einfügen statischer Daten (Listen ...) umfassen.Create.sql
:Create.cmd
. Das Ziel besteht hauptsächlich darin, nach Voraussetzungen (Tools, Umgebungsvariablen ...) zu suchen und Parameter an das SQL-Skript zu senden. Es kann auch statische Daten aus CSV-Dateien für Leistungsprobleme in großen Mengen laden .Create.cmd
Datei übergeben.IMHO sollte das dynamische Laden von Daten abhängig von Ihrer Umgebung einen weiteren Schritt erfordern. Entwickler möchten ihre Datenbank mit Test-, Junk- oder gar keinen Daten laden, während Produktionsmanager am anderen Ende Produktionsdaten laden möchten. Ich würde in Betracht ziehen, Testdaten auch in der Quellcodeverwaltung zu speichern (um beispielsweise das Testen von Einheiten zu vereinfachen).
Sobald die erste Version der Datenbank in Produktion gegangen ist, müssen Sie nicht nur Skripte erstellen (hauptsächlich für Entwickler), sondern auch Skripte aktualisieren (basierend auf denselben Prinzipien):
Upgrade.sql
Datei (die andere aufrufen kann), mit der Version N-1 auf Version N aktualisiert werden kann (N ist die Version, die veröffentlicht wird). Ich speichere dieses Skript unter einem Ordner mit dem NamenN-1
.Upgrade.cmd
. Es kann die aktuelle Version (CV) der Datenbank über eine einfache SELECT-Anweisung abrufen, dasUpgrade.sql
unter demCV
Ordner gespeicherte Skript starten und eine Schleife ausführen, bis kein Ordner mehr gefunden wird. Auf diese Weise können Sie automatisch ein Upgrade von beispielsweise N-3 auf N durchführen.Probleme damit sind:
Welche Art von Datenbankobjekten möchten Sie unter Quellcodeverwaltung haben? Nun, ich würde so viel wie möglich sagen, aber nicht mehr ;-) Wenn Sie Benutzer mit Kennwörtern erstellen möchten, geben Sie ihnen ein Standardkennwort (Login / Login, praktisch für Unit-Testzwecke) und ändern Sie das Passwort manuell . Dies passiert häufig bei Oracle, wo Schemas auch Benutzer sind ...
quelle
Wir haben unser Silverlight-Projekt mit MSSQL-Datenbank in der Git-Versionskontrolle. Am einfachsten ist es, sicherzustellen, dass Sie eine abgespeckte Datenbank haben (inhaltlich), und einen vollständigen Speicherauszug von z. B. Visual Studio zu erstellen. Anschließend können Sie in Ihrem Build-Skript 'sqlcmd' ausführen, um die Datenbank auf jedem Entwicklungscomputer neu zu erstellen.
Für die Bereitstellung ist dies nicht möglich, da die Datenbanken zu groß sind. Dies ist der Hauptgrund dafür, dass sie überhaupt in einer Datenbank gespeichert sind.
quelle
Ich bin der festen Überzeugung, dass eine Datenbank Teil der Quellcodeverwaltung und zu einem großen Teil Teil des Erstellungsprozesses sein sollte. Wenn es sich um eine Quellcodeverwaltung handelt, habe ich beim Schreiben einer gespeicherten Prozedur in SQL dieselben Codierungssicherungen wie beim Schreiben einer Klasse in C #. Dazu füge ich ein DB-Skriptverzeichnis in meinen Quellbaum ein. Dieses Skriptverzeichnis enthält nicht unbedingt eine Datei für ein Objekt in der Datenbank. Das wäre ein Schmerz im Hintern! Ich entwickle in meiner Datenbank nur ein, was ich in meinem Code-Projekt tun würde. Wenn ich dann zum Einchecken bereit bin, mache ich einen Unterschied zwischen der letzten Version meiner Datenbank und der aktuellen, an der ich arbeite. Ich benutze dafür SQL Compare und es generiert ein Skript aller Änderungen. Dieses Skript wird dann mit einer bestimmten Namenskonvention in meinem Verzeichnis db_update gespeichert. 1234_TasksCompletedInThisIteration wobei die Nummer die nächste Nummer in der Gruppe der bereits vorhandenen Skripte ist und der Name beschreibt, was beim Einchecken getan wird. Ich mache dies auf diese Weise, weil als Als Teil meines Erstellungsprozesses beginne ich mit einer neuen Datenbank, die dann programmgesteuert mit den Skripten in diesem Verzeichnis erstellt wird. Ich habe eine benutzerdefinierte NAnt-Aufgabe geschrieben, die jedes Skript durchläuft und seinen Inhalt auf der nackten Datenbank ausführt. Wenn ich Daten benötige, um in die Datenbank zu gelangen, habe ich natürlich auch Skripte zum Einfügen von Daten. Dies hat auch viele Vorteile. Erstens sind alle meine Sachen versioniert. Zweitens ist jeder Build ein neuer Build, was bedeutet, dass keine hinterhältigen Dinge in meinen Entwicklungsprozess eindringen (z. B. schmutzige Daten, die zu Kuriositäten im System führen). Drittens, wenn ein neuer Mann zum Entwicklerteam hinzugefügt wird, muss er einfach auf dem neuesten Stand sein und sein lokaler Entwickler wird im laufenden Betrieb für ihn gebaut. Viertens kann ich Testfälle (ich habe es nicht als "Komponententest" bezeichnet!) In meiner Datenbank ausführen, da der Status der Datenbank bei jedem Build zurückgesetzt wird (was bedeutet, dass ich meine Repositorys testen kann, ohne mir Gedanken über das Hinzufügen von Testdaten zu der Datenbank machen zu müssen db).
Dies ist nicht jedermanns Sache.
Dies ist nicht für jedes Projekt. Normalerweise arbeite ich an Projekten auf der grünen Wiese, was mir diese Bequemlichkeit ermöglicht!
quelle
Anstatt auf Argumente des weißen Turms einzugehen, ist hier eine Lösung, die für mich bei Problemen der realen Welt sehr gut funktioniert hat.
Das Erstellen einer Datenbank von Grund auf kann als Verwaltung von SQL-Skripten zusammengefasst werden.
DBdeploy ist ein Tool, das den aktuellen Status einer Datenbank überprüft - z. B. welche Skripte zuvor ausgeführt wurden, welche Skripte zur Ausführung verfügbar sind und welche Skripte daher ausgeführt werden müssen.
Anschließend werden alle erforderlichen Skripte zusammengestellt und ausgeführt. Anschließend wird aufgezeichnet, welche Skripte ausgeführt wurden.
Es ist nicht das schönste oder komplexeste Werkzeug - aber mit sorgfältiger Verwaltung kann es sehr gut funktionieren. Es ist Open Source und leicht erweiterbar. Sobald das Ausführen der Skripte ordnungsgemäß erledigt ist, können einige zusätzliche Komponenten wie ein Shell-Skript, das die neuesten Skripte auscheckt und dbdeploy für eine bestimmte Instanz ausführt, problemlos hinzugefügt werden.
Eine gute Einführung finden Sie hier:
http://code.google.com/p/dbdeploy/wiki/GettingStarted
quelle
Sie können feststellen , dass Liquibase viele Griffe , was Sie suchen.
quelle
Jeder Entwickler sollte über eine eigene lokale Datenbank verfügen und die Quellcodeverwaltung verwenden, um sie im Team zu veröffentlichen. Meine Lösung ist hier: http://dbsourcetools.codeplex.com/ Viel Spaß, - Nathan
quelle