Mécanismes de suivi des modifications du schéma de base de données [fermé]

135

Quelles sont les meilleures méthodes pour suivre et / ou automatiser les modifications de schéma de base de données? Notre équipe utilise Subversion pour le contrôle de version et nous avons pu automatiser certaines de nos tâches de cette manière (pousser les builds vers un serveur intermédiaire, déployer du code testé sur un serveur de production), mais nous continuons à mettre à jour la base de données manuellement. Je voudrais trouver ou créer une solution qui nous permette de travailler efficacement sur des serveurs avec différents environnements tout en continuant à utiliser Subversion comme backend à travers lequel le code et les mises à jour de la base de données sont transférés vers divers serveurs.

De nombreux logiciels courants incluent des scripts de mise à jour automatique qui détectent la version de la base de données et appliquent les modifications nécessaires. Est-ce la meilleure façon de le faire même à plus grande échelle (sur plusieurs projets et parfois dans plusieurs environnements et langues)? Si tel est le cas, existe-t-il un code existant qui simplifie le processus ou est-il préférable de simplement lancer notre propre solution? Quelqu'un a-t-il déjà implémenté quelque chose de similaire et l'a-t-il intégré dans les hooks post-commit de Subversion, ou est-ce une mauvaise idée?

Bien qu'une solution prenant en charge plusieurs plates-formes soit préférable, nous devons absolument prendre en charge la pile Linux / Apache / MySQL / PHP car la majorité de notre travail se fait sur cette plate-forme.

pix0r
la source

Réponses:

56

Dans le monde de Rails, il y a le concept de migrations, des scripts dans lesquels les modifications apportées à la base de données sont effectuées dans Ruby plutôt qu'une version SQL spécifique à la base de données. Votre code de migration Ruby finit par être converti en DDL spécifique à votre base de données actuelle; cela rend le changement de plate-forme de base de données très facile.

Pour chaque modification que vous apportez à la base de données, vous écrivez une nouvelle migration. Les migrations ont généralement deux méthodes: une méthode "ascendante" dans laquelle les modifications sont appliquées et une méthode "descendante" dans laquelle les modifications sont annulées. Une seule commande met la base de données à jour et peut également être utilisée pour amener la base de données vers une version spécifique du schéma. Dans Rails, les migrations sont conservées dans leur propre répertoire dans le répertoire du projet et sont archivées dans le contrôle de version comme tout autre code de projet.

Ce guide Oracle sur les migrations Rails couvre assez bien les migrations.

Les développeurs utilisant d'autres langages ont examiné les migrations et ont implémenté leurs propres versions spécifiques à la langue. Je connais Ruckusing , un système de migrations PHP qui est modelé sur les migrations de Rails; c'est peut-être ce que vous recherchez.

Joey deVilla
la source
1
Ruckusing FTW - nous l'avons adapté à notre système db et en sommes très satisfaits.
Piskvor a quitté le bâtiment
Il est maintenant situé sur github: github.com/ruckus/ruckusing-migrations
50

Nous utilisons quelque chose de similaire à bcwoord pour garder nos schémas de base de données synchronisés sur 5 installations différentes (production, préparation et quelques installations de développement), et sauvegardés dans le contrôle de version, et cela fonctionne plutôt bien. Je vais élaborer un peu:


Pour synchroniser la structure de la base de données, nous avons un seul script, update.php, et un certain nombre de fichiers numérotés 1.sql, 2.sql, 3.sql, etc. Le script utilise une table supplémentaire pour stocker le numéro de version actuelle du base de données. Les fichiers N.sql sont fabriqués à la main, pour passer de la version (N-1) à la version N de la base de données.

Ils peuvent être utilisés pour ajouter des tables, ajouter des colonnes, migrer des données d'un ancien vers un nouveau format de colonne, puis supprimer la colonne, insérer des lignes de données «maître» telles que les types d'utilisateurs, etc. Fondamentalement, il peut tout faire et avec des données appropriées scripts de migration, vous ne perdrez jamais de données.

Le script de mise à jour fonctionne comme ceci:

  • Connectez-vous à la base de données.
  • Faites une sauvegarde de la base de données en cours (parce que des choses se tromper) [mysqldump].
  • Créez une table de comptabilité (appelée _meta) si elle n'existe pas.
  • Lire la VERSION actuelle à partir de la table _meta. Supposons 0 si non trouvé.
  • Pour tous les fichiers .sql numérotés plus haut que VERSION, exécutez-les dans l'ordre
  • Si l'un des fichiers a produit une erreur: revenir à la sauvegarde
  • Sinon, mettez à jour la version de la table de comptabilité avec le fichier .sql le plus élevé exécuté.

Tout va dans le contrôle de source, et chaque installation a un script pour mettre à jour vers la dernière version avec une seule exécution de script (appel de update.php avec le mot de passe de base de données approprié, etc.). Nous SVN mettons à jour les environnements de préparation et de production via un script qui appelle automatiquement le script de mise à jour de la base de données, de sorte qu'une mise à jour de code est fournie avec les mises à jour de base de données nécessaires.

Nous pouvons également utiliser le même script pour recréer la base de données entière à partir de zéro; nous déposons et recréons simplement la base de données, puis exécutons le script qui repeuplera complètement la base de données. Nous pouvons également utiliser le script pour remplir une base de données vide pour des tests automatisés.


Il n'a fallu que quelques heures pour mettre en place ce système, il est conceptuellement simple et tout le monde obtient le schéma de numérotation des versions, et cela a été inestimable pour pouvoir avancer et faire évoluer la conception de la base de données, sans avoir à communiquer ou à exécuter manuellement les modifications. sur toutes les bases de données.

Attention cependant lorsque vous collez des requêtes depuis phpMyAdmin! Ces requêtes générées incluent généralement le nom de la base de données, ce que vous ne voulez certainement pas car cela cassera vos scripts! Quelque chose comme CREATE TABLE mydb. newtable(...) échouera si la base de données du système ne s'appelle pas mydb. Nous avons créé un hook SVN de pré-commentaire qui interdira les fichiers .sql contenant la mydbchaîne, ce qui est un signe certain que quelqu'un a copié / collé depuis phpMyAdmin sans vérification appropriée.

rix0rrr
la source
Comment avez-vous géré les collisions? Plusieurs développeurs modifiant le même élément dans la base de données, par exemple une procédure stockée? Cela peut arriver si vous travaillez en même temps sur la même branche, ou si vous avez deux lignes de développement en cours (deux branches)
Asaf Mesika
Les collisions étaient très rares; la seule chose qui s'est réellement produite est que deux personnes essaient de créer le même fichier N.sql. Bien sûr, le premier gagne et le second est obligé de renommer le numéro suivant le plus élevé et de réessayer. Cependant, nous n'avions pas le contrôle de version de la base de données sur une branche.
rix0rrr
12

Mon équipe écrit tous les changements de base de données et valide ces scripts dans SVN, avec chaque version de l'application. Cela permet des modifications incrémentielles de la base de données, sans perdre aucune donnée.

Pour passer d'une version à l'autre, il vous suffit d'exécuter l'ensemble des scripts de modification, et votre base de données est à jour, et vous avez toujours toutes vos données. Ce n'est peut-être pas la méthode la plus simple, mais elle est certainement efficace.

Bois Brandon
la source
1
comment rédigez-vous tous les changements?
Smith
10

Le problème ici est vraiment de permettre aux développeurs de script leurs propres modifications locales dans le contrôle de code source à partager avec l'équipe. Je suis confronté à ce problème depuis de nombreuses années et je me suis inspiré des fonctionnalités de Visual Studio pour les professionnels de la base de données. Si vous voulez un outil open-source avec les mêmes fonctionnalités, essayez ceci: http://dbsourcetools.codeplex.com/ Amusez-vous bien, - Nathan.


la source
10

Si vous êtes toujours à la recherche de solutions: nous vous proposons un outil appelé neXtep designer. C'est un environnement de développement de base de données avec lequel vous pouvez mettre toute votre base de données sous contrôle de version. Vous travaillez sur un référentiel contrôlé par version où chaque changement peut être suivi.

Lorsque vous devez publier une mise à jour, vous pouvez valider vos composants et le produit générera automatiquement le script de mise à niveau SQL à partir de la version précédente. Bien sûr, vous pouvez générer ce SQL à partir de 2 versions quelconques.

Ensuite, vous avez de nombreuses options: vous pouvez prendre ces scripts et les mettre dans votre SVN avec le code de votre application afin qu'il soit déployé par votre mécanisme existant. Une autre option consiste à utiliser le mécanisme de livraison de neXtep: les scripts sont exportés dans quelque chose appelé "package de livraison" (scripts SQL + descripteur XML), et un installateur peut comprendre ce package et le déployer sur un serveur cible tout en assurant la cohérence structurelle, la dépendance vérifier, enregistrer la version installée, etc.

Le produit est GPL et est basé sur Eclipse donc il fonctionne sous Linux, Mac et Windows. Il prend également en charge Oracle, Mysql et Postgresql pour le moment (le support DB2 est en cours). Jetez un œil au wiki où vous trouverez des informations plus détaillées: http://www.nextep-softwares.com/wiki

Christophe Fondacci
la source
Semble intéressant. At-il également une interface de ligne de commande ou est-il prévu?
Piskvor a quitté le bâtiment
8

Scott Ambler produit une grande série d'articles (et co-écrit un livre ) sur le refactoring de bases de données, avec l'idée que vous devriez essentiellement appliquer les principes et pratiques TDD pour maintenir votre schéma. Vous configurez une série de tests d'unité de données de structure et de départ pour la base de données. Ensuite, avant de changer quoi que ce soit, vous modifiez / écrivez des tests pour refléter ce changement.

Nous faisons cela depuis un certain temps maintenant et cela semble fonctionner. Nous avons écrit du code pour générer des vérifications de base du nom de colonne et du type de données dans une suite de tests unitaires. Nous pouvons réexécuter ces tests à tout moment pour vérifier que la base de données dans l'extraction SVN correspond à la base de données en direct que l'application exécute réellement.

Il s'avère que les développeurs modifient parfois leur base de données sandbox et négligent de mettre à jour le fichier de schéma dans SVN. Le code dépend alors d'un changement de base de données qui n'a pas été enregistré. Ce type de bogue peut être extrêmement difficile à cerner, mais la suite de tests le détecte tout de suite. C'est particulièrement intéressant si vous l'avez intégré dans un plan d'intégration continue plus large.

Sam McAfee
la source
7

Videz votre schéma dans un fichier et ajoutez-le au contrôle de code source. Ensuite, un simple diff vous montrera ce qui a changé.

programmeur mort
la source
1
Le dump doit être en SQL, comme un mysqldump, les dumps d'Oracle sont binaires.
Osama Al-Maadeed
7
Il existe également un problème plus fondamental avec les différences de schéma. Comment différencier une colonne drop + add d'un changement de nom de colonne. La réponse est simple: vous ne pouvez pas. C'est la raison pour laquelle vous devez enregistrer les opérations de changement de schéma réelles.
psp
Le diff montrera que l'une des colonnes a disparu, tandis que l'autre est apparue (sauf si elles portent le même nom), et la plupart du temps, cela suffit. Le script de chaque changement de schéma est une bonne façon de procéder, bien sûr: dans Drupal, cela est géré par un hook spécial, par exemple.
deadprogrammer
5

C'est un peu peu technologique, et il existe peut-être une meilleure solution, mais vous pouvez simplement stocker votre schéma dans un script SQL qui peut être exécuté pour créer la base de données. Je pense que vous pouvez exécuter une commande pour générer ce script, mais je ne connais pas la commande malheureusement.

Ensuite, validez le script dans le contrôle de code source avec le code qui fonctionne dessus. Lorsque vous devez modifier le schéma avec le code, le script peut être archivé avec le code qui nécessite le schéma modifié. Ensuite, les différences sur le script indiqueront les différences sur les changements de schéma.

Avec ce script, vous pouvez l'intégrer à DBUnit ou à une sorte de script de construction, il semble donc qu'il puisse s'intégrer à vos processus déjà automatisés.

Mike Stone
la source
Ouais, c'est à peu près ce que nous avons en place en ce moment. Malheureusement, cela ne nous donne pas un moyen facile de modifier les bases de données existantes - le script SQL généré par mysqldump suppose que vous créez la table à partir de zéro (ou écrasez une table si elle existe). Nous avons besoin de quelque chose d'un peu plus high-tech car il doit appliquer une séquence d'instructions ALTER TABLE à la base de données, et pour le faire correctement, il doit être conscient de l'état actuel de la base de données.
pix0r
5

Si vous utilisez C #, jetez un œil à Subsonic, un outil ORM très utile, mais qui génère également un script sql pour recréer votre schéma et / ou vos données. Ces scripts peuvent ensuite être placés sous contrôle de code source.

http://subsonicproject.com/

Dan
la source
Semble être une URL morte à partir de ce moment.
Mark Schultheiss
5

J'ai utilisé la structure de projet de base de données suivante dans Visual Studio pour plusieurs projets et cela a plutôt bien fonctionné:

Base de données

Modifier les scripts

0.PreDeploy.sql

1.SchemaChanges.sql

2.DataChanges.sql

3.Permissions.sql

Créer des scripts

Sprocs

Les fonctions

Vues

Notre système de construction met ensuite à jour la base de données d'une version à l'autre en exécutant les scripts dans l'ordre suivant:

1.PreDeploy.sql

2.SchemaChanges.sql

Contenu du dossier Créer des scripts

2.DataChanges.sql

3.Permissions.sql

Chaque développeur vérifie ses modifications pour un bogue / fonctionnalité particulier en ajoutant son code à la fin de chaque fichier. Une fois qu'une version majeure est terminée et branchée dans le contrôle de code source, le contenu des fichiers .sql dans le dossier Change Scripts est supprimé.

tbreffni
la source
5

Nous utilisons une solution très simple mais efficace.

Pour les nouvelles installations, nous avons un fichier metadata.sql dans le référentiel qui contient tout le schéma de base de données, puis dans le processus de construction, nous utilisons ce fichier pour générer la base de données.

Pour les mises à jour, nous ajoutons les mises à jour dans le logiciel codé en dur. Nous le gardons codé en dur parce que nous n'aimons pas résoudre les problèmes avant que ce ne soit vraiment un problème, et ce genre de chose ne s'est pas avéré être un problème jusqu'à présent.

Donc, dans notre logiciel, nous avons quelque chose comme ceci:

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

Ce code vérifiera si la base de données est en version 1 (qui est stockée dans une table créée automatiquement), si elle est obsolète, alors la commande est exécutée.

Pour mettre à jour le fichier metadata.sql dans le référentiel, nous exécutons ces mises à niveau localement, puis extrayons les métadonnées complètes de la base de données.

La seule chose qui arrive de temps en temps, c'est d'oublier la validation du metadata.sql, mais ce n'est pas un problème majeur car il est facile à tester sur le processus de construction et la seule chose qui pourrait arriver est de faire une nouvelle installation avec une base de données obsolète et l'a mise à niveau lors de la première utilisation.

De plus, nous ne prenons pas en charge les rétrogradations, mais c'est par conception, si quelque chose se brise sur une mise à jour, nous avons restauré la version précédente et corrigé la mise à jour avant de réessayer.

Fabio Gomes
la source
4

Je crée des dossiers nommés d'après les versions de construction et j'y mets des scripts de mise à niveau et de rétrogradation. Par exemple, vous pouvez avoir les dossiers suivants: 1.0.0, 1.0.1 et 1.0.2. Chacun contient le script qui vous permet de mettre à niveau ou de rétrograder votre base de données entre les versions.

Si un client ou un client vous appelle avec un problème avec la version 1.0.1 et que vous utilisez 1.0.2, ramener la base de données à sa version ne sera pas un problème.

Dans votre base de données, créez une table appelée «schéma» où vous mettez la version actuelle de la base de données. Ensuite, il est facile d'écrire un programme qui peut mettre à niveau ou rétrograder votre base de données.

Tout comme Joey l'a dit, si vous êtes dans un monde Rails, utilisez Migrations. :)

Louis Salin
la source
3

Pour mon projet PHP actuel, nous utilisons l'idée de migrations de rails et nous avons un répertoire de migrations dans lequel nous conservons le titre des fichiers "migration_XX.sql" où XX est le numéro de la migration. Actuellement, ces fichiers sont créés à la main au fur et à mesure des mises à jour, mais leur création pourrait être facilement modifiée.

Ensuite, nous avons un script appelé "Migration_watcher" qui, comme nous sommes en pré-alpha, s'exécute actuellement à chaque chargement de page et vérifie s'il existe un nouveau fichier migration_XX.sql où XX est plus grand que la version de migration actuelle. Si c'est le cas, il exécute tous les fichiers migration_XX.sql jusqu'au plus grand nombre sur la base de données et le tour est joué! les changements de schéma sont automatisés.

Si vous avez besoin de la possibilité de revenir en arrière, le système nécessiterait beaucoup de réglages, mais c'est simple et cela fonctionne très bien pour notre équipe assez petite jusqu'à présent.

Eric Scrivner
la source
3

Je recommanderais d'utiliser Ant (multiplateforme) pour le côté "scripting" (car il peut pratiquement parler à n'importe quelle base de données via jdbc) et Subversion pour le référentiel source. Ant vous permettra de "sauvegarder" votre base de données dans des fichiers locaux, avant d'effectuer des modifications. 1. sauvegarder le schéma de base de données existant dans un fichier via Ant 2. contrôle de version vers le référentiel Subversion via Ant 3. envoyer de nouvelles instructions sql à db via Ant

Cruz
la source
3

Toad pour MySQL a une fonction appelée comparaison de schémas qui vous permet de synchroniser 2 bases de données. C'est le meilleur outil que j'ai utilisé jusqu'à présent.

Petah
la source
3

J'aime la façon dont Yii gère les migrations de bases de données. Une migration est essentiellement une implémentation de script PHP CDbMigration. CDbMigrationdéfinit une upméthode qui contient la logique de migration. Il est également possible de mettre en œuvre une downméthode pour prendre en charge l'inversion de la migration. Alternativement, safeUpou safeDownpeut être utilisé pour s'assurer que la migration est effectuée dans le contexte d'une transaction.

L'outil de ligne de commande de Yii prend en yiiccharge la création et l'exécution de migrations. Les migrations peuvent être appliquées ou inversées, une par une ou par lots. La création d'une migration aboutit à un code pour l'implémentation d'une classe PHP CDbMigration, dont le nom est unique en fonction d'un horodatage et d'un nom de migration spécifié par l'utilisateur. Toutes les migrations qui ont été précédemment appliquées à la base de données sont stockées dans une table de migration.

Pour plus d'informations, consultez l' article Migration de base de données du manuel.

Ton van den Heuvel
la source
2

Les migrations IMHO ont un énorme problème:

La mise à niveau d'une version à une autre fonctionne bien, mais faire une nouvelle installation d'une version donnée peut prendre une éternité si vous avez des centaines de tables et une longue histoire de changements (comme nous le faisons).

L'exécution de tout l'historique des deltas depuis la ligne de base jusqu'à la version actuelle (pour des centaines de bases de données clients) peut prendre beaucoup de temps.

Edson Medina
la source
0

Il existe un outil de ligne de commande mysql-diff qui compare les schémas de base de données, où le schéma peut être une base de données en direct ou un script SQL sur disque. Il convient à la plupart des tâches de migration de schéma.

stepancheg
la source