wake-up-neo.com

Ordnungsgemäße Verwaltung der Datenbankbereitstellung mit SSDT- und Visual Studio 2012-Datenbankprojekten

Ich bin in der Forschungsphase und versuche, 2012 Database Projects auf ein bestehendes kleines Projekt anzuwenden. Ich bin ein C # -Entwickler und kein DBA. Daher kann ich mit Best Practices nicht besonders gut umgehen. Ich habe jetzt einige Stunden lang nach Google und Stackoverflow gesucht, weiß aber immer noch nicht, wie ich mit einigen wichtigen Bereitstellungsszenarien richtig umgehen soll.

1) Wie verwalte ich im Verlauf mehrerer Entwicklungszyklen mehrere Versionen meiner Datenbank? Wie verwalte ich einen Client in Version 3 meiner Datenbank, der auf Version 8 aktualisiert werden soll? Derzeit verwalten wir handgefertigte Schema- und Datenmigrationsskripts für jede Version unseres Produkts. Müssen wir dies noch separat tun oder gibt es etwas in dem neuen Paradigma, das dies unterstützt oder ersetzt?

2) Wenn sich das Schema so ändert, dass Daten verschoben werden müssen, wie kann dies am besten gehandhabt werden? Ich gehe davon aus, dass das Pre-Deployment-Skript einige Arbeiten ausführt, um die Daten zu erhalten, und dass das Post-Deploy-Skript sie dann wieder an die richtige Stelle zurücksetzt. Ist das so oder gibt es etwas Besseres?

3) Jeder andere Rat oder jede Anleitung, wie man am besten mit diesen neuen Technologien umgeht, wird ebenfalls sehr geschätzt!

PDATE: Seit ich diese Frage ursprünglich gestellt habe, ist mein Verständnis des Problems ein wenig gewachsen, und obwohl ich eine praktikable Lösung gefunden habe, war es nicht ganz die Lösung, auf die ich gehofft hatte. Hier ist eine Umformulierung meines Problems:

Das Problem, das ich habe, ist rein datenbezogen. Wenn ich einen Client in Version 1 meiner Anwendung habe und ihn auf Version 5 meiner Anwendung aktualisieren möchte, hätte ich keine Probleme, wenn die Datenbank keine Daten enthält. Ich würde SSDT einfach auf intelligente Weise Schemata vergleichen und die Datenbank in einem Durchgang migrieren lassen. Leider haben Kunden Daten, so einfach ist das nicht. Das Schema ändert sich von Version 1 meiner Anwendung zu Version 2 zu Version 3 (usw.). Alle Auswirkungsdaten. Meine derzeitige Strategie zur Datenverwaltung erfordert, dass ich für jedes Versions-Upgrade ein Skript verwalte (1 auf 2, 2 auf 3 usw.). Dies hindert mich daran, direkt von Version 1 meiner Anwendung zu Version 5 zu wechseln, da ich kein Datenmigrationsskript habe, um direkt dorthin zu gelangen. Die Aussicht, benutzerdefinierte Upgradeskripte für jeden Client zu erstellen oder Upgradeskripte zu verwalten, um von jeder Version zu jeder höheren Version zu wechseln, ist exponentiell nicht zu handhaben. Was ich gehofft hatte, war, dass es eine Art Strategie gab, die SSDT ermöglicht und die Verwaltung der Datenseite der Dinge einfacher macht, vielleicht sogar so einfach wie die Schemaseite der Dinge. Meine jüngsten Erfahrungen mit SSDT haben mir keine Hoffnung auf eine solche Strategie gegeben, aber ich würde es gerne anders herausfinden.

60
Charles Josephs

Ich habe selbst daran gearbeitet, und ich kann Ihnen sagen, dass es nicht einfach ist.

Erstens, um die Antwort von JT zu beantworten - Sie können "Versionen" nicht verwerfen, selbst wenn SSDT über deklarative Aktualisierungsmechanismen verfügt. SSDT leistet einen "ziemlich anständigen" Job (vorausgesetzt, Sie kennen alle Schalter und Fallstricke), um ein Quellschema in ein beliebiges Zielschema zu verschieben, und es ist wahr, dass dies an sich keine Überprüfung erfordert, aber es hat keine Ahnung, wie es zu verwalten ist. " Datenbewegung "(zumindest nicht das ich sehen kann!). Genau wie bei DBProj haben Sie sich also in Pre/Post-Skripten auf Ihre eigenen Geräte verlassen. Da die Datenbewegungsskripten von einem bekannten Start- und Endschemazustand abhängen, können Sie die Versionierung der Datenbank nicht vermeiden. Die "Datenbewegungs" -Skripte müssen daher auf einen versionierten Snapshot des Schemas angewendet werden. Dies bedeutet, dass Sie eine Datenbank nicht willkürlich von v1 auf v8 aktualisieren können und erwarten, dass die Datenbewegungsskripte von v2 auf v8 funktionieren (wahrscheinlich nicht) brauche ein v1 data motion script).

Leider sehe ich beim SSDT-Publishing keinen Mechanismus, mit dem ich dieses Szenario auf integrierte Weise handhaben kann. Das heißt, Sie müssen Ihr eigenes Gerüst hinzufügen.

Der erste Trick besteht darin, Versionen in der Datenbank (und im SSDT-Projekt) zu verfolgen. Ich habe angefangen, einen Trick in DBProj zu verwenden, und habe ihn SSDT übergeben. Nach einigen Recherchen hat sich herausgestellt, dass auch andere diesen Trick verwenden. Sie können eine DB Extended-Eigenschaft auf die Datenbank selbst anwenden (nennen Sie sie "BuildVersion" oder "AppVersion" oder ähnliches) und den Versionswert darauf anwenden. Sie können diese erweiterte Eigenschaft dann im SSDT-Projekt selbst erfassen, und SSDT fügt sie als Skript hinzu (Sie können dann die Veröffentlichungsoption aktivieren, die erweiterte Eigenschaften enthält). Ich benutze dann SQLCMD-Variablen, um die Quell- und Zielversionen zu identifizieren, die im aktuellen Durchgang angewendet werden. Sobald Sie das Delta der Versionen zwischen der Quelle (Projekt-Snapshot) und dem Ziel (Ziel-DB, die aktualisiert werden soll) identifiziert haben, können Sie alle Snapshots finden, die angewendet werden müssen. Leider ist dies in inside der SSDT-Bereitstellung schwierig, und Sie müssen es wahrscheinlich in die Build- oder Bereitstellungspipeline verschieben (wir verwenden automatisierte TFS-Bereitstellungen und führen hierzu benutzerdefinierte Aktionen aus).

Die nächste Hürde besteht darin, Momentaufnahmen des Schemas mit den zugehörigen Datenbewegungsskripten zu speichern. In diesem Fall ist es hilfreich, die Skripte so idempotent wie möglich zu gestalten (dh Sie können die Skripte ohne schädliche Nebenwirkungen erneut ausführen). Es ist hilfreich, Skripte zu teilen, die sicher von Skripten ausgeführt werden können, die nur einmal ausgeführt werden müssen. Wir machen dasselbe mit statischen Referenzdaten (Wörterbuch oder Nachschlagetabellen) - mit anderen Worten, wir haben eine Bibliothek von MERGE-Skripten (eine pro Tabelle), die die Referenzdaten synchron halten, und diese Skripten sind in der Veröffentlichung enthalten -Deployment-Skripte (über den Befehl SQLCMD: r). Das Wichtige dabei ist, dass Sie müssen sie in der richtigen Reihenfolge ausführen, falls eine dieser Referenztabellen FK-Referenzen zueinander hat. Wir fügen sie der Reihe nach in das Haupt-Post-Deployment-Skript ein, und es hilft uns, ein Tool zu erstellen, mit dem diese Skripten für uns generiert werden. Außerdem wird die Abhängigkeitsreihenfolge aufgelöst. Wir führen dieses Generierungstool am Ende einer "Version" aus, um den aktuellen Status der statischen Referenzdaten zu erfassen. Alle Ihre anderen Datenbewegungsskripte sind im Grunde genommen Sonderfälle und werden höchstwahrscheinlich nur einmal verwendet. In diesem Fall haben Sie zwei Möglichkeiten: Sie können eine IF-Anweisung für die db build/app-Version verwenden oder Sie können die 1-Zeit-Skripte nach dem Erstellen jedes Snapshot-Pakets löschen.

Es ist hilfreich, sich daran zu erinnern, dass SSDT die FK-Überprüfungsbeschränkungen deaktiviert und sie erst wieder aktiviert, nachdem die Post-Deployment-Skripts ausgeführt wurden. Dies gibt Ihnen die Möglichkeit, beispielsweise neue Nicht-Null-Felder auszufüllen (Sie müssen übrigens die Option aktivieren, temporäre "intelligente" Standardwerte für Nicht-Null-Spalten zu generieren, damit dies funktioniert). FK-Prüfungseinschränkungen sind jedoch nur für Tabellen deaktiviert, die SSDT aufgrund einer Schemaänderung neu erstellt. In anderen Fällen sind Sie dafür verantwortlich, sicherzustellen, dass Datenbewegungsskripten in der richtigen Reihenfolge ausgeführt werden, um Beanstandungen aufgrund von Prüfbeschränkungen zu vermeiden (oder Sie müssen sie in Ihren Skripten manuell deaktivieren/wieder aktivieren).

DACPAC kann Ihnen helfen, da DACPAC im Wesentlichen eine Momentaufnahme ist. Es enthält mehrere XML-Dateien, die das Schema beschreiben (ähnlich der Build-Ausgabe des Projekts), die jedoch zum Zeitpunkt der Erstellung eingefroren sind. Sie können dann SQLPACKAGE.EXE oder den Bereitstellungsanbieter verwenden, um diesen Paket-Snapshot zu veröffentlichen. Ich habe nicht genau herausgefunden, wie die DACPAC-Versionierung verwendet werden soll, da sie eher mit "registrierten" Daten-Apps verknüpft ist. Wir bleiben daher bei unserem eigenen Versionsschema, fügen jedoch unsere eigenen Versionsinformationen in den DACPAC-Dateinamen ein.

Ich wünschte, ich hätte ein schlüssigeres und ausführlicheres Beispiel, aber wir arbeiten auch hier noch an den Problemen.

Eine Sache, die an SSDT wirklich scheiße ist, ist, dass es im Gegensatz zu DBProj derzeit nicht erweiterbar ist. Obwohl es in vielen verschiedenen Dingen eine viel bessere Arbeit leistet als DBProj, können Sie sein Standardverhalten nur überschreiben, wenn Sie eine Methode in den Pre-/Post-Skripten finden, um ein Problem zu umgehen. Eines der Probleme, die wir derzeit zu lösen versuchen, ist, dass die Standardmethode zum Neuerstellen einer Tabelle für Aktualisierungen (CCDR) wirklich stinkt, wenn Sie zig Millionen Datensätze haben.

-UPDATE: Ich habe diesen Beitrag seit einiger Zeit nicht gesehen, aber anscheinend war er in letzter Zeit aktiv. Ich dachte, ich würde ein paar wichtige Hinweise hinzufügen: Wenn Sie VS2012 verwenden, enthält die SSDT-Version vom Juni 2013 jetzt Daten Das Vergleichstool ist integriert und bietet Erweiterungspunkte. Das heißt, Sie können jetzt Build Contributors und Deployment Plan Modifiers für das Projekt einbeziehen.

59
DevPrime

Ich habe keine wirklich nützlichen Informationen zu diesem Thema gefunden, aber ich habe einige Zeit damit verbracht, die Werkzeuge kennenzulernen, zu basteln und zu spielen, und ich denke, ich habe einige akzeptable Antworten auf meine Frage gefunden. Dies sind nicht unbedingt die besten Antworten. Ich weiß immer noch nicht, ob es andere Mechanismen oder Best Practices gibt, um diese Szenarien besser zu unterstützen.

Die Pre- und Post-Deploy-Skripts für eine bestimmte Version der Datenbank werden nur zum Migrieren von Daten aus der vorherigen Version verwendet. Zu Beginn jedes Entwicklungszyklus werden die Skripte bereinigt und im Verlauf der Entwicklung werden sie mit den für die sichere Migration von Daten von der Vorgängerversion auf die neue Version erforderlichen SQL-Daten konkretisiert. Die einzige Ausnahme sind statische Daten in der Datenbank. Diese Daten sind zur Entwurfszeit bekannt und in Form von T-SQL-MERGE-Anweisungen dauerhaft in den Post-Deploy-Skripten enthalten. Auf diese Weise können Sie jede Version der Datenbank mit dem neuesten Veröffentlichungsskript in einer neuen Umgebung bereitstellen. Am Ende jedes Entwicklungszyklus wird ein Veröffentlichungsskript von der vorherigen auf die neue Version generiert. Dieses Skript enthält generierte SQL-Anweisungen zum Migrieren des Schemas und der handgefertigten Bereitstellungsskripten. Ja, ich weiß, dass das Veröffentlichungs-Tool direkt für eine Datenbank verwendet werden kann, aber dies ist keine gute Option für unsere Kunden. Ich kenne auch Dacpac-Dateien, bin mir aber nicht sicher, wie ich sie verwenden soll. Das generierte Veröffentlichungsskript scheint die beste Option zu sein, die ich für Produktions-Upgrades kenne.

Um meine Szenarien zu beantworten:

1) Um eine Datenbank von v3 auf v8 zu aktualisieren, müsste ich das generierte Veröffentlichungsskript für v4, dann für v5, dann für v6 usw. ausführen. Dies ist sehr ähnlich wie wir es jetzt tun. Es ist gut verstanden und Datenbankprojekte scheinen das Erstellen/Verwalten dieser Skripte viel einfacher zu machen.

2) Wenn sich das Schema von Daten unterhalb ändert, werden die Daten mithilfe der Pre- und Post-Deploy-Skripts an den Ort migriert, an dem sie für die neue Version benötigt werden. Betroffene Daten werden im Wesentlichen im Pre-Deploy-Skript gesichert und im Post-Deploy-Skript wiederhergestellt.

3) Ich bin immer noch auf der Suche nach Ratschlägen, wie ich mit diesen Tools in diesen und anderen Szenarien am besten arbeiten kann. Wenn ich hier etwas falsch gemacht habe oder wenn es irgendwelche anderen Fallstricke gibt, die mir bekannt sein sollten, lassen Sie es mich bitte wissen! Vielen Dank!

9
Charles Josephs

Nach meiner Erfahrung mit der Verwendung von SSDT geht der Begriff der Versionsnummern (d. H. V1, v2 ... vX usw. ...) für Datenbanken ein bisschen verloren. Dies liegt daran, dass SSDT ein Entwicklungsparadigma anbietet, das als deklarative Datenbankentwicklung bezeichnet wird. Dies bedeutet, dass Sie SSDT mitteilen, in welchem ​​Zustand sich Ihr Schema befinden soll, und dass SSDT die Verantwortung dafür übernimmt, dass es in diesen Zustand versetzt wird, indem Sie es mit dem vergleichen, was Sie bereits haben. In diesem Paradigma verschwindet der Gedanke, v4, dann v5 usw. bereitzustellen.

Ihre Pre- und Post-Deployment-Skripte sind, wie Sie richtig angeben, zum Verwalten von Daten vorhanden.

Ich hoffe, das hilft.

JT

4
jamiet

Ich wollte nur sagen, dass dieser Thread bisher ausgezeichnet war.

Ich habe mit genau den gleichen Bedenken gerungen und versuche, dieses Problem in unserer Organisation mit einer ziemlich großen Legacy-Anwendung anzugehen. Wir haben begonnen, auf SSDT umzusteigen (in einem TFS-Zweig), sind jedoch an dem Punkt angelangt, an dem wir den Bereitstellungsprozess und die Verwaltung von benutzerdefinierten Migrationen sowie Referenz-/Nachschlagedaten auf diesem Weg wirklich verstehen müssen.

Um die Sache noch weiter zu verkomplizieren, besteht unsere Anwendung aus einer Codebasis, kann jedoch pro "Kunde" angepasst werden. Wir haben also ungefähr 190 Datenbanken für dieses eine Projekt, nicht nur etwa 3, wie es wahrscheinlich normal ist. Wir führen die ganze Zeit Bereitstellungen durch und richten sogar ziemlich oft neue Kunden ein. Wir verlassen uns jetzt stark auf PowerShell mit inkrementellen Versionsskripten der alten Schule (und zugehörigen Skripten, um einen neuen Kunden mit dieser Version zu erstellen). Ich habe vor, einen Beitrag zu leisten, sobald wir alles herausgefunden haben, aber teilen Sie uns bitte mit, was Sie sonst noch gelernt haben. Ich glaube, wir werden am Ende benutzerdefinierte Release-Skripte pro Version beibehalten, aber wir werden sehen. Die Idee, jedes Skript innerhalb des Projekts zu verwalten und eine From- und To-SqlCmd-Variable einzuschließen, ist sehr interessant. Wenn wir das tun, würden wir wahrscheinlich auf dem Weg zurückschneiden und die wirklich alten Upgrade-Skripte physisch löschen, sobald alle diese Version überschritten haben.

Übrigens - Randnotiz - Zum Thema Abfallminimierung haben wir nur eine Weile darüber nachgedacht, wie die Durchsetzung der korrekten Namens-/Datentypkonventionen für Spalten sowie die automatische Generierung für alle Primär- und Fremdschlüssel basierend automatisiert werden kann über Namenskonventionen sowie Index- und Prüfbeschränkungen usw. Das Schwierigste war, sich mit den Abweichern auseinanderzusetzen, die nicht den Regeln entsprachen. Vielleicht teile ich das auch eines Tages mit, wenn jemand daran interessiert ist, aber im Moment muss ich diese Bereitstellung, Migration und Referenzdatengeschichte intensiv verfolgen. Danke noch einmal. Es ist, als ob ihr genau gesprochen habt, was in meinem Kopf war und was ihr heute Morgen gesucht habt.

3
Ryan White