2008-08-27 4 views
32

Cela semble être une zone négligée qui pourrait vraiment utiliser un aperçu. Quelles sont vos meilleures pratiques pour:Comment gérez-vous les mises à niveau de schéma vers une base de données de production?

  • rendant une procédure de mise à niveau
  • soutenant en cas d'erreurs
  • Code synchronisation et base de données des changements
  • test avant le déploiement
  • mécanique de modifier la table

etc ...

+0

Je suis surpris qu'il n'y ait pas plus de réponses ici - peut-être besoin de tags Oracle ou sqlserver spécifiques? –

+0

bonne idée, merci! –

Répondre

3

Voilà une excellente question. (Il y a de fortes chances que cela finisse par un débat sur une base de données normalisée ou dénormalisée ... que je ne vais pas commencer ... maintenant, pour une entrée.)

J'ai fait (ajoutera plus quand j'ai plus de temps ou besoin d'une pause)

conception du client - c'est où la méthode VB de inline sql (même avec des instructions préparées) vous obtient des ennuis. Vous pouvez passer AGES simplement en trouvant ces déclarations. Si vous utilisez quelque chose comme Hibernate et mettez autant de SQL dans les requêtes nommées vous avez un seul endroit pour la plupart des sql (rien de pire que d'essayer de tester sql qui se trouve dans une déclaration IF et vous ne frappez pas le "trigger" critères dans vos tests pour cette déclaration IF). Avant d'utiliser hibernate (ou d'autres orms) quand je ferais SQL directement dans JDBC ou ODBC, je mettrais toutes les instructions sql comme des champs publics d'un objet (avec une convention de nommage) ou dans un fichier de propriétés (également avec un nom convention pour les valeurs dites PREP_STMT_xxxx Et utiliser soit la réflexion soit itérer sur les valeurs au démarrage dans a) les cas de test b) le démarrage de l'application (certains rdbms permettent de pré-compiler avec des instructions préparées avant l'exécution, donc au démarrage pré-compiler les prep-stmts au démarrage pour faire l'auto-test de l'application.Même pour 100 de déclarations sur un bon rdbms c'est seulement quelques secondes et une seule fois.Et il a beaucoup sauvé mes fesses.Sur un projet, les DBA ne communiquaient pas (une équipe différente, dans un pays différent) et le schéma semblait changer NUITÉ, sans raison. Et chaque matin, nous avons eu une liste d'où il a cassé l'application, au démarrage. Si vous avez besoin d'une fonctionnalité adhoc, placez-la dans une classe bien nommée (c'est-à-dire, une convention de nommage facilite les tests automatiques) qui agit comme une sorte d'usine pour vous (c'est-à-dire construit la requête). Vous allez devoir écrire le code équivalent de toute façon, juste mettre dans un endroit où vous pouvez le tester. Vous pouvez même écrire des méthodes de test de base sur le même objet ou dans une classe séparée.

Si vous le pouvez, essayez également d'utiliser des procédures stockées. Ils sont un peu plus difficiles à tester que ci-dessus. Certains db ne pré-valident pas le sql dans les procs stockés par rapport au schéma lors de la compilation uniquement au moment de l'exécution. Cela implique généralement de prendre une copie de la structure du schéma (pas de données) et ensuite de créer tous les procs stockés contre cette copie (dans le cas où l'équipe de db effectuant les changements n'a pas validé correctement). Ainsi, la structure peut être vérifiée. mais comme un point de gestion du changement stocké procs sont super. Au changement, tous l'obtiennent. Surtout quand les changements de db sont le résultat de changements de processus métier. Et tous les langages (java, vb, etc obtiennent le changement)

J'ai l'habitude d'installer aussi une table que j'utilise appelée system_setting etc. Dans ce tableau nous gardons un identificateur de VERSION. Cela permet aux bibliothèques clientes de se connecter et de valider si elles sont valides pour cette version du schéma. En fonction des modifications apportées à votre schéma, vous ne voulez pas autoriser les clients à se connecter s'ils peuvent corrompre votre schéma (c'est-à-dire que vous n'avez pas beaucoup de règles référentielles dans la base de données, mais sur le client). Cela dépend si vous allez également avoir plusieurs versions de client (ce qui arrive dans les applications non-web, c'est-à-dire qu'elles utilisent un mauvais binaire). Vous pouvez également avoir des outils de traitement par lots, etc. Une autre approche que j'ai également faite est de définir un ensemble de schémas à des versions d'opération dans une sorte de fichier de propriétés ou encore dans une table system_info. Cette table est chargée lors de la connexion, et ensuite utilisée par chaque "manager" (j'ai habituellement une sorte d'API côté client pour faire la plupart des choses db) pour valider cette opération si c'est la bonne version. Ainsi la plupart des opérations peuvent réussir, mais vous pouvez aussi échouer (jeter une exception) sur des méthodes obsolètes et vous dire POURQUOI.

gérer le changement de schéma -> mettez-vous à jour la table ou ajoutez-vous des relations 1-1 aux nouvelles tables? J'ai vu beaucoup de magasins qui accèdent toujours aux données via une vue pour cette raison. Cela permet de changer les noms des tables, les colonnes, etc. J'ai joué avec l'idée de traiter les vues comme des interfaces dans COM. c'est à dire. vous ajoutez une nouvelle vue pour les nouvelles fonctionnalités/versions. Souvent, ce que vous obtenez ici, c'est que vous pouvez avoir beaucoup de rapports (en particulier les rapports personnalisés de l'utilisateur final) qui supposent des formats de table. Les vues vous permettent de déployer un nouveau format de table mais prennent en charge les applications client existantes (souvenez-vous de tous ces rapports ad hoc agaçants).

Également besoin d'écrire des scripts de mise à jour et de restauration. et encore TEST, TEST, TEST ...

------------ OKAY - C'EST UN TEMPS DE DISCUSSION ALÉATOIRE DE BIT --------------

Avait en fait un grand projet commercial (ie magasin de logiciels) où nous avons eu le même problème. L'architecture était à 2 niveaux et ils utilisaient un produit un peu comme PHP mais pré-php. Même chose. nom différent. de toute façon je suis entré dans la version 2 ....

Il coûtait BEAUCOUP D'ARGENT pour faire des mises à jour. Beaucoup. c'est à dire. Donner des semaines de consultation gratuite sur le site.

Et il était sur le point de vouloir ajouter de nouvelles fonctionnalités ou optimiser le code. Une partie du code existant utilisait des procédures stockées, donc nous avions des points communs où nous pouvions gérer le code. mais d'autres domaines étaient ce balisage sql embarqué en html. Ce qui était génial pour arriver rapidement sur le marché, mais avec chaque interaction de nouvelles fonctionnalités, le coût a au moins doublé pour tester et maintenir.Donc, quand nous cherchions à sortir le code de type php, mettre des couches de données (c'était 2001-2002, pré ORM etc) et ajouter beaucoup de nouvelles fonctionnalités (commentaires des clients) regardé cette question de savoir comment créer des MISES À NIVEAU dans le système. Ce qui est un gros problème, car les mises à niveau coûtent beaucoup d'argent à faire correctement. Maintenant, la plupart des modèles et toutes les autres choses que les gens discutent avec un certain niveau d'énergie traite avec le code OO qui fonctionne, mais qu'en est-il du fait que vos données doivent a) intégrer à cette logique, b) la signification et la structure de les données peuvent changer au fil du temps, et souvent à cause de la façon dont les données fonctionnent, beaucoup de sous-processus/applications dans l'organisation de vos clients ont besoin de ces données -> rapports ad hoc ou rapports personnalisés complexes, ainsi que des tâches par lots Cela a été fait pour les flux de données personnalisés, etc

Dans cet esprit, j'ai commencé à jouer avec quelque chose un peu à gauche du champ. Il a également quelques hypothèses. a) les données sont beaucoup plus lues que écrites. b) les mises à jour se produisent, mais pas au niveau des banques. un ou deux par seconde disent. L'idée était d'appliquer une vue COM/Interface à la manière dont les données étaient accédées par les clients sur un ensemble de tables CONCRETE (qui variaient avec les changements de schéma). Vous pouvez créer une vue séparée pour chaque opération de type: mise à jour, suppression, insertion et lecture. C'est important. Les vues sont soit mappées directement à une table, soit vous permettent de déclencher une table fictive qui effectue les mises à jour ou les insertions réelles, etc. Ce que je voulais réellement, c'était une indirection de niveau trappable qui pourrait encore être utilisée par les rapports Crystal. - Pour les insertions, les mises à jour et les suppressions, vous pouvez également utiliser des procs stockés. Et vous aviez une version pour chaque version du produit. De cette façon, votre version 1.0 avait sa version du schéma, et si les tables changeaient, vous auriez toujours la version 1.0 VIEWS mais avec la NOUVELLE logique dorsale pour mapper aux nouvelles tables si nécessaire, mais vous aviez aussi des vues de version 2.0 qui supporteraient de nouveaux champs, etc. Il s'agissait simplement de soutenir des rapports ad hoc, ce qui est probablement la raison pour laquelle vous avez un produit si vous êtes un commercial et non un codeur. (Votre produit peut être de la merde mais si vous avez le meilleur rapport dans le monde, vous pouvez toujours gagner, l'inverse est vrai - votre produit peut être la meilleure caractéristique sage, mais si c'est le pire sur les rapports, vous pouvez facilement perdre).

okay, espérons que certaines de ces idées aident.

+6

Comment cela est-il devenu la réponse acceptée? Comment répond-il aux points de la question initiale? –

+1

Cette réponse est-elle liée à la question? –

4

En règle générale, ma règle est: "L'application doit gérer son propre schéma." Cela signifie que les scripts de mise à niveau de schéma font partie de tout package de mise à niveau pour l'application et s'exécutent automatiquement au démarrage de l'application. En cas d'erreur, l'application ne démarre pas et la transaction de script de mise à niveau n'est pas validée. L'inconvénient est que l'application doit avoir un accès complet au schéma (cela agace les DBA).

J'ai eu beaucoup de succès en utilisant la fonctionnalité Hibernates SchemaUpdate pour gérer les structures de table. Laissant les scripts de mise à niveau pour gérer uniquement l'initialisation des données réelles et la suppression occasionnelle des colonnes (SchemaUpdate ne fait pas cela). En ce qui concerne les tests, étant donné que les mises à niveau font partie de l'application, leur test fait partie du cycle d'essai de l'application. Après réflexion: En tenant compte de certaines des critiques dans d'autres messages ici, notez que la règle dit «c'est propre». Cela s'applique uniquement lorsque l'application possède le schéma comme c'est généralement le cas avec un logiciel vendu en tant que produit. Si votre logiciel partage une base de données avec un autre logiciel, utilisez d'autres méthodes.

4

Je suis un grand fan de Red Gate produits qui aident à créer des paquets SQL pour mettre à jour les schémas de base de données. Les scripts de base de données peuvent être ajoutés au contrôle de source pour faciliter la gestion des versions et la restauration.

2

Ce sont tous des sujets de poids, mais voici ma recommandation pour la mise à jour.

Vous n'avez pas spécifié votre plate-forme, mais pour les environnements de construction NANT, j'utilise Tarantino. Pour chaque mise à jour de base de données que vous êtes prêt à valider, vous créez un script de modification (en utilisant RedGate ou un autre outil). Lorsque vous construisez en production, Tarantino vérifie si le script a été exécuté sur la base de données (il ajoute une table à votre base de données pour garder la trace). Sinon, le script est exécuté. Il faut tout le travail manuel (lire: erreur humaine) hors de la gestion des versions de base de données.

8

liquibase.org:

  1. il comprend hiberner définitions.
  2. il génère une meilleure mise à jour le schéma sql que mise en veille prolongée
  3. il enregistre les mises à niveau ont été apportées à une base de données
  4. il gère les changements en deux étapes (c.-à supprimer une colonne « foo » puis renommer une colonne différente de « foo «)
  5. il gère le concept de mises à jour conditionnelles
  6. le développeur écoute réellement à la communauté (avec mise en veille prolongée si vous n'êtes pas dans le « in » ou un débutant - vous êtes essentiellement ignoré.)

http://www.liquibase.org

+0

[Flyway] (https://flywaydb.org) est un autre choix, similaire dans ses intentions à Liquibase: migrations de bases de données rendues faciles, vous permettant d'évoluer votre schéma. Flyway est construit en Java, conçu pour être utilisé à partir de Java mais peut aussi être appelé à partir de la ligne de commande. Les deux Liquibase et Flyway semblent être des projets bien conçus. –

6

avis

l'application devrait jamais gérer une mise à jour du schéma. C'est une catastrophe qui attend de se produire. Les données survivent aux applications et dès que plusieurs applications essaient de travailler avec les mêmes données (l'application de production + une application de reporting par exemple), il y a de fortes chances qu'elles utilisent les mêmes bibliothèques sous-jacentes ... faire leur propre mise à jour db ... amusez-vous avec que mess.

0

Comme Pat a dit, l'utilisation liquibase. Surtout quand vous avez plusieurs développeurs avec leurs propres bases de données de développement apportant des modifications qui feront partie de la base de données de production. S'il n'y a qu'un seul dev, comme sur un projet que je suis maintenant (ha), je viens de valider les changements de schéma en fichiers texte SQL dans un repo CVS, que je vérifie par lots sur le serveur de production lorsque le les changements de code vont po

Mais la liquibase est mieux organisée que ça!

Questions connexes