web-dev-qa-db-fra.com

Comment gérer correctement le déploiement de la base de données avec les projets de base de données SSDT et Visual Studio 2012?

Je suis en phase de recherche pour essayer d'adopter les projets de base de données 2012 sur un petit projet existant. Je suis un développeur C #, pas un DBA, donc je ne maîtrise pas particulièrement les meilleures pratiques. Je recherche sur Google et stackoverflow depuis quelques heures, mais je ne sais toujours pas comment gérer correctement certains scénarios de déploiement clés.

1) Au cours de plusieurs cycles de développement, comment gérer plusieurs versions de ma base de données? Si j'ai un client sur la v3 de ma base de données et que je souhaite les mettre à niveau vers la v8, comment gérer cela? Nous gérons actuellement des schémas artisanaux et des scripts de migration de données pour chaque version de notre produit. Avons-nous encore besoin de le faire séparément ou y a-t-il quelque chose dans le nouveau paradigme qui le supporte ou le remplace?

2) Si le schéma change de telle manière que les données doivent être déplacées, quelle est la meilleure façon de gérer cela? Je suppose que certains travaux sont effectués dans le script de pré-déploiement pour préserver les données, puis le script de post-déploiement les remet au bon endroit. Est-ce ainsi ou y a-t-il quelque chose de mieux?

3) Tout autre conseil ou orientation sur la meilleure façon de travailler avec ces nouvelles technologies est également très apprécié!

MISE À JOUR: Ma compréhension du problème a un peu augmenté depuis que j'ai posé cette question à l'origine et même si j'ai trouvé une solution viable, ce n'était pas tout à fait la solution que j'espérais. Voici une reformulation de mon problème:

Le problème que j'ai est purement lié aux données. Si j'ai un client sur la version 1 de mon application et que je souhaite les mettre à niveau vers la version 5 de mon application, je n'aurais aucun problème à le faire si leur base de données n'avait pas de données. Je laisserais simplement SSDT comparer intelligemment les schémas et migrer la base de données en une seule fois. Malheureusement, les clients ont des données, ce n'est donc pas si simple. Le schéma passe de la version 1 de mon application à la version 2 à la version 3 (etc.) toutes les données d'impact. Ma stratégie actuelle de gestion des données nécessite de maintenir un script pour chaque mise à niveau de version (1 à 2, 2 à 3, etc.). Cela m'empêche d'aller directement de la version 1 de mon application à la version 5 car je n'ai pas de script de migration de données pour y aller directement. La perspective de créer des scripts de mise à niveau personnalisés pour chaque client ou de gérer des scripts de mise à niveau pour passer de chaque version à chaque version supérieure est exponentiellement ingérable. Ce que j'espérais, c'était qu'il existait une sorte de stratégie SSDT permettant de gérer la partie données des choses plus facilement, peut-être même aussi facilement que la partie schéma des choses. Ma récente expérience avec SSDT ne m'a donné aucun espoir d'une telle stratégie mais j'aimerais le découvrir différemment.

60
Charles Josephs

J'y travaille moi-même et je peux vous dire que ce n'est pas facile.

Tout d'abord, pour répondre à la réponse de JT - vous ne pouvez pas ignorer les "versions", même avec la mécanique de mise à jour déclarative que SSDT possède. SSDT fait un travail "assez décent" (à condition que vous connaissiez tous les commutateurs et accrochages) de déplacer n'importe quel schéma source vers n'importe quel schéma cible, et il est vrai que cela ne nécessite pas de vérification en soi, mais il n'a aucune idée de la façon de gérer " mouvement de données "(du moins pas que je puisse voir!). Donc, tout comme DBProj, vous avez laissé vos propres appareils dans les scripts de pré/post. Étant donné que les scripts de mouvement de données dépendent d'un état de schéma de début et de fin connu, vous ne pouvez pas éviter de versionner la base de données. Les scripts de "mouvement de données" doivent donc être appliqués à un instantané versionné du schéma, ce qui signifie que vous ne pouvez pas mettre à jour arbitrairement une base de données de v1 à v8 et vous attendre à ce que les scripts de mouvement de données v2 à v8 fonctionnent (vraisemblablement, vous ne le feriez pas besoin d'un script de mouvement de données v1).

Malheureusement, je ne vois aucun mécanisme dans la publication SSDT qui me permette de gérer ce scénario de manière intégrée. Cela signifie que vous devrez ajouter votre propre échafaudage.

La première astuce consiste à suivre les versions dans la base de données (et le projet SSDT). J'ai commencé à utiliser une astuce dans DBProj, et l'ai apportée à SSDT, et après avoir fait quelques recherches, il s'avère que d'autres l'utilisent également. Vous pouvez appliquer une propriété étendue DB à la base de données elle-même (appelez-la "BuildVersion" ou "AppVersion" ou quelque chose comme ça), et appliquez-lui la valeur de version. Vous pouvez ensuite capturer cette propriété étendue dans le projet SSDT lui-même, et SSDT l'ajoutera en tant que script (vous pouvez ensuite vérifier l'option de publication qui inclut des propriétés étendues). J'utilise ensuite des variables SQLCMD pour identifier les versions source et cible appliquées dans la passe actuelle. Une fois que vous avez identifié le delta des versions entre la source (instantané du projet) et la cible (base de données cible sur le point d'être mise à jour), vous pouvez trouver tous les instantanés qui doivent être appliqués. Malheureusement, cela est difficile à faire à partir de à l'intérieur le déploiement SSDT, et vous devrez probablement le déplacer vers le pipeline de génération ou de déploiement (nous utilisons des déploiements automatisés TFS et avons des actions personnalisées pour ce faire).

Le prochain obstacle est de conserver des instantanés du schéma avec leurs scripts de mouvement de données associés. Dans ce cas, cela aide à rendre les scripts aussi idempotents que possible (ce qui signifie que vous pouvez réexécuter les scripts sans aucun effet secondaire néfaste). Il permet de séparer les scripts qui peuvent être réexécutés en toute sécurité à partir de scripts qui doivent être exécutés une seule fois. Nous faisons la même chose avec les données de référence statiques (dictionnaire ou tables de recherche) - en d'autres termes, nous avons une bibliothèque de scripts MERGE (un par table) qui gardent les données de référence synchronisées, et ces scripts sont inclus dans le post -scripts de déploiement (via la commande SQLCMD: r). La chose importante à noter ici est que vous devez les exécuter dans le bon ordre au cas où l'une de ces tables de référence aurait des références FK les unes aux autres. Nous les incluons dans le script principal post-déploiement dans l'ordre, et cela aide que nous ayons créé un outil qui génère ces scripts pour nous - il résout également l'ordre des dépendances. Nous exécutons cet outil de génération à la fin d'une "version" pour capturer l'état actuel des données de référence statiques. Tous vos autres scripts de mouvement de données seront essentiellement des cas spéciaux et très probablement à usage unique. Dans ce cas, vous pouvez effectuer l'une des deux opérations suivantes: vous pouvez utiliser une instruction IF par rapport à la version db build/app, ou vous pouvez supprimer les scripts 1 fois après la création de chaque package d'instantanés.

Il est utile de se rappeler que SSDT désactivera les contraintes de vérification FK et ne les réactivera qu'après l'exécution des scripts post-déploiement. Cela vous donne une chance de remplir de nouveaux champs non nuls, par exemple (en passant, vous devez activer l'option pour générer des valeurs par défaut "intelligentes" temporaires pour les colonnes non nulles pour que cela fonctionne). Cependant, les contraintes de vérification FK ne sont désactivées que pour les tables que SSDT recrée en raison d'une modification de schéma. Pour les autres cas, vous êtes responsable de veiller à ce que les scripts de mouvement de données s'exécutent dans le bon ordre pour éviter les plaintes de contraintes de vérification (ou vous les avez manuellement désactivés/réactivés dans vos scripts).

DACPAC peut vous aider car DACPAC est essentiellement un instantané. Il contiendra plusieurs fichiers XML décrivant le schéma (similaire à la sortie de génération du projet), mais figé dans le temps au moment où vous le créez. Vous pouvez ensuite utiliser SQLPACKAGE.EXE ou le fournisseur de déploiement pour publier cet instantané de package. Je n'ai pas tout à fait compris comment utiliser le versioning DACPAC, car il est plus lié aux applications de données "enregistrées", nous sommes donc coincés avec notre propre schéma de version, mais nous mettons nos propres informations de version dans le nom de fichier DACPAC.

J'aimerais avoir un exemple plus concluant et plus exhaustif à fournir, mais nous travaillons toujours sur les problèmes ici aussi.

Une chose qui craint vraiment à propos de SSDT est que contrairement à DBProj, il n'est actuellement pas extensible. Bien qu'il fasse un bien meilleur travail que DBProj pour beaucoup de choses différentes, vous ne pouvez pas remplacer son comportement par défaut à moins que vous ne trouviez une méthode à l'intérieur des scripts pré/post pour contourner un problème. L'un des problèmes que nous essayons de résoudre en ce moment est que la méthode par défaut de recréation d'une table pour les mises à jour (CCDR) pue vraiment lorsque vous avez des dizaines de millions d'enregistrements.

-MISE À JOUR: Je n'ai pas vu ce message depuis un certain temps, mais apparemment, il a été actif récemment, alors j'ai pensé ajouter quelques notes importantes: si vous utilisez VS2012, la version de juin 2013 de SSDT a maintenant un Data Outil de comparaison intégré et fournissant également des points d'extensibilité - c'est-à-dire que vous pouvez désormais inclure des contributeurs de construction et des modificateurs de plan de déploiement pour le projet.

59
DevPrime

Je n'ai pas vraiment trouvé d'informations plus utiles sur le sujet, mais j'ai passé un peu de temps à connaître les outils, à bricoler et à jouer, et je pense avoir trouvé des réponses acceptables à ma question. Ce ne sont pas nécessairement les meilleures réponses. Je ne sais toujours pas s'il existe d'autres mécanismes ou meilleures pratiques pour mieux prendre en charge ces scénarios, mais voici ce que j'ai trouvé:

Les scripts de pré et post-déploiement pour une version donnée de la base de données ne sont utilisés que pour migrer les données de la version précédente. Au début de chaque cycle de développement, les scripts sont nettoyés et au fur et à mesure du développement, ils s'épanouissent avec tout ce dont SQL a besoin pour migrer en toute sécurité les données de la version précédente vers la nouvelle. La seule exception ici est les données statiques dans la base de données. Ces données sont connues au moment de la conception et maintiennent une présence permanente dans les scripts Post-Deploy sous la forme d'instructions T-SQL MERGE. Cela permet de déployer n'importe quelle version de la base de données dans un nouvel environnement avec uniquement le dernier script de publication. À la fin de chaque cycle de développement, un script de publication est généré de la version précédente vers la nouvelle. Ce script inclura SQL généré pour migrer le schéma et les scripts de déploiement fabriqués à la main. Oui, je sais que l'outil de publication peut être utilisé directement contre une base de données, mais ce n'est pas une bonne option pour nos clients. Je connais également les fichiers dacpac mais je ne sais pas vraiment comment les utiliser. Le script de publication généré semble être la meilleure option que je connaisse pour les mises à niveau de production.

Donc pour répondre à mes scénarios:

1) Pour mettre à niveau une base de données de la v3 à la v8, je devrais exécuter le script de publication généré pour la v4, puis pour la v5, puis pour la v6, etc. Ceci est très similaire à la façon dont nous le faisons maintenant. C'est bien compris et les projets de base de données semblent faciliter la création/maintenance de ces scripts.

2) Lorsque le schéma change de sous les données, les scripts de pré et post-déploiement sont utilisés pour migrer les données vers l'endroit où elles doivent aller pour la nouvelle version. Les données affectées sont essentiellement sauvegardées dans le script de pré-déploiement et remises en place dans le script de post-déploiement.

3) Je recherche toujours des conseils sur la meilleure façon de travailler avec ces outils dans ces scénarios et dans d'autres. Si je me trompe, ou s'il y a d'autres problèmes que je devrais connaître, faites-le moi savoir! Merci!

9
Charles Josephs

Dans mon expérience de l'utilisation de SSDT, la notion de numéros de version (c'est-à-dire v1, v2 ... vX etc ...) pour les bases de données disparaît un peu. En effet, SSDT offre un paradigme de développement connu sous le nom de développement de base de données déclarative, ce qui signifie que vous dites à SSDT dans quel état vous voulez que votre schéma se trouve, puis laissez SSDT prendre la responsabilité de le mettre dans cet état en comparant avec ce que vous avez déjà. Dans ce paradigme la notion de déployer v4 puis v5 etc .... s'en va.

Vos scripts de pré et post-déploiement, comme vous le dites correctement, existent pour la gestion des données.

J'espère que ça t'as aidé.

JT

4
jamiet

Je voulais juste dire que ce fil jusqu'à présent a été excellent.

J'ai été aux prises avec les mêmes préoccupations et j'essaie de résoudre ce problème dans notre organisation, sur une application héritée assez importante. Nous avons commencé le processus de transition vers SSDT (sur une branche TFS), mais nous sommes au point où nous avons vraiment besoin de comprendre le processus de déploiement et de gérer les migrations personnalisées et les données de référence/recherche en cours de route.

Pour compliquer encore les choses, notre application est une base de code mais peut être personnalisée par `` client '', nous avons donc environ 190 bases de données avec lesquelles nous traitons, pour ce seul projet, pas seulement 3 ou plus, ce qui est probablement normal. Nous effectuons des déploiements tout le temps et configurons même de nouveaux clients assez souvent. Nous comptons beaucoup sur PowerShell maintenant avec des scripts de version incrémentielle à l'ancienne (et des scripts associés pour créer un nouveau client dans cette version). Je prévois de contribuer une fois que nous aurons tout compris, mais veuillez partager tout ce que vous avez appris. Je pense que nous finirons par maintenir des scripts de version personnalisés par version, mais nous verrons. L'idée de maintenir chaque script dans le projet et d'inclure une variable From et To SqlCmd est très intéressante. Si nous faisions cela, nous élaguerions probablement le long du chemin, supprimant physiquement les très anciens scripts de mise à niveau une fois que tout le monde aurait dépassé cette version.

BTW - Note latérale - Sur le sujet de la minimisation des déchets, nous venons également de passer beaucoup de temps à découvrir comment automatiser l'application des conventions de nommage/type de données appropriées pour les colonnes, ainsi que la génération automatique de toutes les clés primaires et étrangères, basée sur sur les conventions de dénomination, ainsi que sur les contraintes d'indexation et de vérification, etc. La partie la plus difficile a été de gérer les "déviants" qui ne respectaient pas les règles. Peut-être que je partagerai cela un jour si quelqu'un est intéressé, mais pour l'instant, je dois poursuivre ce déploiement, la migration et les données de référence de manière intensive. Merci encore. C'est comme si vous parliez exactement de ce que j'avais dans ma tête et que vous cherchiez ce matin.

3
Ryan White