2008-10-31 8 views
0

Veuillez pardonner ma longue question. J'ai une idée pour un design sur lequel je pourrais utiliser quelques commentaires. Est-ce une bonne idée de le faire? Et quelles sont les chutes de fosse dont je devrais être conscient? Y a-t-il d'autres implémentations similaires qui sont meilleures?Correctif dynamique des bases de données

Ma situation est la suivante:
Je travaille sur une ré-écriture d'une application Windows Forms qui se connecte à un serveur SQL 2008 (plus tôt, il était SQL 2005) serveur. L'application est un "système expert" pour une société d'ingénierie où nous stockons des données structurées sur les constructions. Nous avons le contrôle de toutes les installations du logiciel client, nous n'avons pas de clients ou d'utilisateurs externes, ils sont tous internes à l'entreprise, et on peut leur faire confiance pour ne rien faire de malveillant pour le logiciel ou la base de données.

La conception actuelle n'a pas trop de tables (environ 10 - 20) mais certaines d'entre elles ont des millions d'enregistrements qui appartiennent à plusieurs centaines de constructions. La performance des systèmes a été satisfaisante jusqu'à présent, mais elle commence à se dégrader à mesure que nous repoussons les limites de la conception. Dans le cadre de la réécriture, j'envisage de diviser la base de données en une base de données principale et plusieurs bases de données «enfant» où chacune décrit une construction. Chaque base de données enfant doit être de conception identique. Cela devrait éliminer les problèmes de performance que nous voyons aujourd'hui puisque les données stockées dans chaque base de données seraient inférieures à un pour cent de la quantité totale de données. Mon souci est qu'au lieu de maintenir une base de données, nous allons maintenant obtenir des centaines de bases de données qui doivent être tenues à jour. Le système évolue constamment au fur et à mesure que les exigences de l'entreprise changent (vous savez comment c'est), et pendant que nous essayons de réduire le nombre de changements, les changements vont arriver. Nous aurons donc besoin d'un système où nous garderons une trace de toutes les modifications apportées à la base de données du système afin qu'elles puissent être appliquées aux bases de données enfant. La mise à jour de l'application client ne sera pas un problème, nous avons un bon contrôle de cet aspect.

Je pense à un système de suivi des modifications dans lequel nous stockons des scripts de base de données pour toutes les modifications d'une table dans la base de données master. Nous pouvons ensuite donner à chaque changement un numéro de version et nous pouvons stocker un numéro de version actuel dans chaque base de données enfant. Lorsque le programme client se connecte à une base de données enfant, nous pouvons vérifier le numéro de version de la base de données par rapport au numéro de version actuel et s'il existe des correctifs dont le numéro de version est supérieur au numéro de version de la base de données enfant. la base de données enfant à la dernière version. Comme je le vois, cela devrait bien fonctionner. Toute modification du système sera d'abord testée et validée avant d'être validée en tant que nouvelle version de la base de données. La modification sera ensuite appliquée à la base de données la première fois qu'un utilisateur l'ouvre. Je suppose que nous ouvririons la base de données en mode exclusif tout en appliquant les changements, mais tant que les changements ne sont pas trop fréquents cela ne devrait pas poser de problème.

Alors, qu'en pensez-vous? Est-ce que ça va marcher? Est-ce que l'un d'entre vous a fait quelque chose de similaire? Devrions-nous abandonner la solution et opter plutôt pour le système monolithique?

Répondre

1

J'ai une situation similaire ici, bien que j'utilise MySQL. Chaque base de données a une table de versions qui contient la version (simplement un entier) et un bref commentaire de ce qui a changé dans cette version. J'utilise un script pour mettre à jour les bases de données. Chaque changement de base de données peut être dans une fonction ou parfois une modification est effectuée par plusieurs fonctions. Les fonctions contiennent le numéro de version dans le nom de la fonction. Le script recherche le numéro de version le plus élevé dans une base de données et applique uniquement les fonctions ayant un numéro de version supérieur dans l'ordre.Cela facilite la mise à jour des bases de données (il suffit d'ajouter de nouvelles fonctions de changement) et me permet de mettre à jour rapidement une base de données récupérée si nécessaire (il suffit de lancer à nouveau le script).

Même en testant les changements avant que cela ne permette des changements défensifs. Si vous effectuez des changements lourds sur une table et que vous voulez jouer en toute sécurité:

def change103(...): 
    "Create new table." 
def change104(...): 
    """Transfer data from old table to new table and make 
     complicated changes in the process. 
    """ 
def change105(...): 
    "Drop old table" 
def change106(...): 
    "Rename new table to old table" 

si change104() est quelque chose qui va mal (et lève une exception), vous pouvez simplement supprimer le déjà converti les données de la nouvelle table, corrigez votre fonction de modification et réexécutez le script.

Mais je ne pense pas que modifier une base de données de façon dynamique lorsqu'un client se connecte est une bonne idée. Parfois, les changements peuvent prendre du temps. Et le logiciel qui accède à une base de données doit correspondre au schéma de la base de données. Vous devez en quelque sorte les synchroniser. Peut-être que vous pourriez distribuer une nouvelle version du logiciel et ensuite vous voulez mettre à jour la base de données quand un client commence réellement à utiliser ce nouveau logiciel. Mais je n'ai pas essayé ça.

2

Avez-vous considéré partitionnement vos grandes tables par 'construction'? Cela pourrait alléger certaines des douleurs de croissance en séparant le stockage pour les tables à travers les fichiers/périphériques physiques sans avoir besoin de changer votre application.

L'ajout de broches (plus de disques) et l'exécution de quelques heures de travail en mode DBA peuvent souvent être moins onéreux que la modification ou l'adaptation d'un logiciel.

Sinon, je suis d'accord avec @heikogerlach et ces postes similaires:

How do I version my ms sql database

Mechanisms for tracking DB schema changes

How do you manage databases in development, test and production?

+0

Nous envisageons toujours de faire des optimisations sur la base de données au lieu de la diviser, mais il y a d'autres raisons pour lesquelles je veux le faire en dehors des performances. Mais merci pour les liens, surtout le dernier était très utile! –

1

mieux ne pas créer des bases de données supplémentaires. À première vue, vous pouvez penser que vous aurez un gain de performance, mais en réalité, vous obtenez un cauchemar de soutien. Rappelez-vous - ce qui peut casser, se casse tôt ou tard.

Il est beaucoup plus simple d'effectuer et d'optimiser les requêtes dans une base de données unique. Il est beaucoup plus facile de gérer les permissions des utilisateurs dans une seule base de données. Il est beaucoup plus facile de faire des sauvegardes cohérentes pour une seule base de données. Comme l'a dit KenG, si vous avez besoin de casser vos grandes tables, envisagez de les partitionner. Et ajoutez quelques lecteurs :)

Mais d'abord exécutez le profileur SQL sur votre base de données et d'optimiser les index et les requêtes. Plusieurs millions de lignes ne sont généralement pas un gros problème à gérer (sauf si votre client a besoin de en cours totalisant plus de la moitié de ceux-ci, auquel cas aucun partitionnement ne peut aider).

1

Je sais que cela est une réponse folle, mais ici, il va ...

J'ai actuellement un scénario similaire où je dois garder le contrôle des versions de base de données dans plusieurs emplacements pour un système utilisant MS SQL Server.

Ce que je fais maintenant utilise Ruby on Rails ActiveRecord Migrations pour garder le contrôle des versions de base de données. Oui, je sais que nous parlons de systèmes Windows mais cela fonctionne très bien pour moi. (En passant, mon système est programmé en VB et.NET)

J'ai installé Rails sur chaque serveur, quand j'ai besoin de mettre à jour le schéma de la base de données, copier les fichiers de migration sur le serveur et lancer rake db: migrate version. En tant qu'effet secondaire, vous disposez d'un ensemble de fichiers de migration pour votre schéma de base de données dans un langage indépendant de la base de données (ruby) que vous pouvez appliquer à d'autres moteurs de base de données.

Je sais que c'est une solution étrange dans laquelle une technologie totalement différente est utilisée mais cela ne fait pas de mal d'apprendre de nouvelles approches. Vous pouvez trouver des informations supplémentaires here.

Je suis devenu un meilleur programmeur .Net depuis que j'ai appris Ruby on Rails. J'ai demandé ici un question à propos de cette approche.