Mécanismes de suivi des modifications de schéma de base de données

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 été en mesure d'automatiser certaines de nos tâches de cette façon (en générant des builds vers un serveur de test, en déployant du code testé sur un serveur de production). Je voudrais trouver ou créer une solution qui nous permette de travailler efficacement sur des serveurs avec des environnements différents tout en continuant à utiliser Subversion comme backend par lequel le code et les mises à jour de DB sont transmis à différents serveurs.

De nombreux logiciels populaires incluent des scripts de mise à jour automatique qui détectent la version DB et appliquent les modifications nécessaires. Est-ce la meilleure façon de le faire même à plus grande échelle (à travers plusieurs projets et parfois plusieurs environnements et langages)? Si oui, existe-t-il un code existant qui simplifie le processus ou est-il préférable de rouler notre propre solution? Est-ce que quelqu'un a implémenté quelque chose de similaire auparavant et l'a 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 est sur cette plate-forme.

0

19 Réponses

C'est un peu low tech, et il pourrait y avoir 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 malheureusement pas la commande.

Ensuite, validez le script dans le contrôle de la 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 avec DBUnit ou une sorte de script de construction, il semble donc qu'il pourrait s'intégrer avec vos processus déjà automatisés.

0
ajouté
Oui, 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 faut 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.
ajouté l'auteur pix0r, source

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

http://subsonicproject.com/

0
ajouté
Ça me va bien?
ajouté l'auteur Dan, source
Semble être une URL morte à ce moment-là.
ajouté l'auteur Mark Schultheiss, source
aime juste subsonique!
ajouté l'auteur TheVillageIdiot, source

Mon équipe écrit toutes les modifications de base de données et les valide dans SVN, avec chaque version de l'application. Ceci permet des changements incrémentaux de la base de données, sans perte de données.

Pour passer d'une version à l'autre, il 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.

0
ajouté
Comment écrivez-vous tous les changements?
ajouté l'auteur Smith, source

Vider votre schéma dans un fichier et l'ajouter au contrôle de la source. Ensuite, un simple diff vous montrera ce qui a changé.

0
ajouté
Le diff montrera que la colonne a disparu, tandis que l'autre est apparue (à moins qu'ils aient le même nom), et la plupart du temps c'est suffisant. Scripter chaque changement de schéma est bien sûr une bonne chose à faire: dans Drupal, ceci est géré par un hook spécial, par exemple.
ajouté l'auteur deadprogrammer, source
Le vidage doit être en SQL, comme un mysqldump, les vidages d'Oracle sont binaires.
ajouté l'auteur Osama Al-Maadeed, source
Il y a aussi un problème plus fondamental avec la différence 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.
ajouté l'auteur psp, source

Nous utilisons une solution très simple mais efficace.

Pour les nouvelles installations, nous avons un fichier metadata.sql dans le dépôt qui contient tout le schéma DB, 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 conservons les données codées 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 révélé être un problème jusqu'à présent.

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

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

Ce code vérifie 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 de valider le fichier metadata.sql, mais ce n'est pas un problème majeur car il est facile de tester le processus de construction et la seule chose qui puisse arriver est de faire une nouvelle installation avec une base de données obsolète et mis à jour sur la première utilisation.

De plus, nous ne supportons pas les downgrades, mais c'est par conception, si quelque chose casse sur une mise à jour, nous avons restauré la version précédente et corrigé la mise à jour avant d'essayer à nouveau.

0
ajouté

Je crée des dossiers nommés d'après les versions de construction et y place 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 rétrograder votre base de données entre les versions.

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

Dans votre base de données, créez une table appelée "schéma" dans laquelle vous placez la version actuelle de la base de données. Ensuite, écrire un programme qui peut mettre à niveau ou rétrograder votre base de données pour vous est facile.

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

0
ajouté

Toad for MySQL dispose d'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'ici.

0
ajouté

Les migrations à mon humble avis ont un énorme problème:

La mise à niveau d'une version à l'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 un long historique de modifications (comme nous le faisons).

Exécuter l'ensemble de l'historique des deltas depuis la version de base jusqu'à la version actuelle (pour des centaines de bases de données clients) peut prendre beaucoup de temps.

0
ajouté

K. Scott Allen a un article décent sur les versions de schémas, qui utilise le concept de scripts de mise à jour incrémentielle / migrations référencé dans d'autres réponses ici; voir http://odetocode.com/Blogs/scott/archive/ 2008/01/31 / 11710.aspx .

0
ajouté

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, mise en scène et quelques installations de développement), et sauvegardés dans le contrôle de version, et cela marche 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 actuel de la 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 format vers un nouveau format puis supprimer la colonne, insérer des lignes de données "maîtres" telles que les types d'utilisateurs, etc. scripts de migration, vous ne perdrez jamais de données.

Le script de mise à jour fonctionne comme ceci:

  • Connect to the database.
  • Make a backup of the current database (because stuff will go wrong) [mysqldump].
  • Create bookkeeping table (called _meta) if it doesn't exist.
  • Read current VERSION from _meta table. Assume 0 if not found.
  • For all .sql files numbered higher than VERSION, execute them in order
  • If one of the files produced an error: roll back to the backup
  • Otherwise, update the version in the bookkeeping table to the highest .sql file executed.

Tout va dans le contrôle de la source, et chaque installation a un script à mettre à jour vers la dernière version avec une seule exécution de script (en appelant update.php avec le mot de passe de base de données approprié, etc.). Nous SVN mettre à jour les environnements de transfert 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 du 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 laissons simplement tomber et recréons 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 un test automatisé.


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

Beware when pasting queries from phpMyAdmin though! Those generated queries usually include the database name, which you definitely don't want since it will break your scripts! Something like CREATE TABLE mydb.newtable(...) will fail if the database on the system is not called mydb. We created a pre-comment SVN hook that will disallow .sql files containing the mydb string, which is a sure sign that someone copy/pasted from phpMyAdmin without proper checking.

0
ajouté
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 sur la même branche ou si vous avez deux lignes de développement (deux branches)
ajouté l'auteur Asaf Mesika, source
Les collisions étaient très rares; la seule chose qui arrive est que deux personnes essaieraient de créer le même fichier N.sql. Bien sûr, le premier gagne et le second est obligé de renommer le prochain nombre le plus élevé et réessayer. Cependant, nous n'avions pas la version de base de données sur une branche.
ajouté l'auteur rix0rrr, source
0
ajouté

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

Pour chaque modification apportée à la base de données, vous écrivez une nouvelle migration. Les migrations ont généralement deux méthodes: une méthode "up" dans laquelle les modifications sont appliquées et une méthode "down" dans laquelle les modifications sont annulées. Une seule commande met à jour la base de données et peut également être utilisée pour amener la base de données à 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 vérifiées dans le contrôle de version comme tout autre code de projet.

ruby on Rails migrations">This Oracle guide to Rails migrations covers migrations quite well.

Les développeurs utilisant d'autres langages ont regardé les migrations et ont implémenté leurs propres versions spécifiques aux langages. Je connais Ruckusing , un système de migration PHP cela est modélisé après les migrations de Rails; Ce pourrait être ce que vous cherchez.

0
ajouté
Il se trouve maintenant à github: github.com/ruckus/ruckusing-migrations
ajouté l'auteur xXx, source
Ruckusing FTW - nous l'avons adapté à notre système db et nous en sommes très satisfaits.
ajouté l'auteur Piskvor, source
Merci d'avoir mentionné Ruckusing
ajouté l'auteur andho, source

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

         

Fonctions

         

Vues

  

Our build system then updates the Base de données from one version to the next by executing the scripts in the following order:

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 bug / une fonctionnalité en ajoutant son code à la fin de chaque fichier. Une fois qu'une version majeure est terminée et ramifiée dans le contrôle de source, le contenu des fichiers .sql dans le dossier Change Scripts est supprimé.

0
ajouté

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

Ensuite, nous avons un script appelé "Migration_watcher" qui, comme nous sommes en pré-alpha, s'exécute actuellement sur 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 de migration_XX.sql jusqu'au plus grand nombre par rapport à la base de données et le tour est joué! les modifications de schéma sont automatisées.

Si vous avez besoin de la possibilité de revenir sur le système, il vous faudra beaucoup de peaufinage, mais c'est simple et cela fonctionne très bien pour notre assez petite équipe jusqu'à maintenant.

0
ajouté

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

Nous faisons cela depuis un moment et cela semble fonctionner. Nous avons écrit du code pour générer des vérifications de nom de colonne et de type de données de base 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 la vérification SVN correspond à la base de données dynamique en cours d'exécution de l'application.

Comme il se trouve, 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 db qui n'a pas été enregistré. Ce genre de bug peut être très difficile à cerner, mais la suite de tests le récupérera tout de suite. Ceci est particulièrement intéressant si vous l'intégrez dans un plan d'intégration continue plus vaste.

0
ajouté

Je recommanderais d'utiliser Ant (cross platform) pour le côté "scripting" (puisqu'il peut pratiquement parler à n'importe quel db là-bas via jdbc) et Subversion pour le dépôt source. Ant vous permettra de "sauvegarder" votre base de données en fichiers locaux, avant de faire des changements. 1. sauvegarde du schéma db existant pour le fichier via Ant 2. Contrôle de version vers le dépôt Subversion via Ant 3. envoyer de nouvelles instructions sql à db via Ant

0
ajouté

Il existe un outil de mysql-diff de ligne de commande 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. C'est bon pour la plupart des tâches de migration de schéma.

0
ajouté

Si vous êtes toujours à la recherche de solutions: nous 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 modification peut être suivie.

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

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

The product is GPL and is based on Eclipse so it runs on Linux, Mac and windows. It also support Oracle, Mysql and Postgresql at the moment (DB2 support is on the way). Have a look at the wiki where you will find more detailed information : http://www.nextep-softwares.com/wiki

0
ajouté
Semble intéressant. A-t-il aussi une interface de ligne de commande ou est-ce prévu?
ajouté l'auteur Piskvor, source

J'aime la façon dont Yii gère les migrations de bases de données. Une migration est essentiellement un script PHP implémentant CDbMigration . CDbMigration définit une méthode up qui contient la logique de migration. Il est également possible d'implémenter une méthode down pour prendre en charge l'inversion de la migration. Alternativement, safeUp ou safeDown peut ê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 yiic contient un support pour créer et exécuter des migrations. Les migrations peuvent être appliquées ou inversées, soit une par une, soit dans un lot. La création d'une migration produit du code pour une classe PHP implémentant CDbMigration , nommée uniquement en fonction d'un horodatage et d'un nom de migration spécifié par l'utilisateur. Toutes les migrations 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.

0
ajouté