Plusieurs réponses à une question de schéma de base de données ont suggéré une table supplémentaire pour normaliser une base de données pour une fonctionnalité qui ne fait pas partie des exigences actuelles (une table UserDepartment pour permettre une relation plusieurs-à-plusieurs entre les employés / utilisateurs et les différents services qu'ils peuvent utiliser appartenir à.).
Pas contre la normalisation. On dirait qu'en matière de conception de base de données, il y a une forte pression pour inclure des fonctionnalités dont ils sont «sûrs» que quelqu'un voudra à l'avenir. Est-il si difficile d'ajouter des tables / champs à la base de données pour tenir compte des fonctionnalités qu'il y a une tendance à sur-concevoir? Ne seraient-ils pas refactorisés ou mis à niveau comme le reste de l'application si nécessaire? Refaire des choses n'est jamais amusant, mais déplacer des données d'une table vers une nouvelle peut être fait. Je ne sais pas où cette ligne de pensée se terminera.
Edit: Il y a tellement d'aversion à cela, je me demande combien de projets finissent par ne pas ajouter une fonctionnalité qui nécessite un changement radical de la base de données ou des approches non normalisées sont prises comme l'ajout d'un champ DepartmentID2 au lieu d'une nouvelle table. La nécessité de plusieurs départements pour un employé est un problème de domaine commun. Je n'ai tout simplement pas remarqué de nombreux schémas de base de données jonchés de relations plusieurs-à-plusieurs.
la source
Réponses:
Il y a un livre entier écrit sur le refactoring de base de données. Tout comme avec le refactoring de code, il existe des moyens standard de refactoring de base de données. La seule différence est que lorsque vous effectuez une refactorisation de code, vous n'avez pas à prendre en compte l'état de l'objet / du code, tandis que dans les bases de données, vous devez prendre en compte les données, car la perte de données n'est pas bonne pour les utilisateurs (ou pour quiconque, en fait ).
Vous pouvez en savoir plus sur la refactorisation de la base de données ici .
la source
La refactorisation du code est facile - vous changez simplement le code et exécutez vos tests de régression.
La refactorisation des bases de données est difficile - vous devez déplacer (une quantité potentiellement énorme) de données, assurez-vous qu'aucune d'entre elles n'est supprimée, assurez-vous que les contraintes sont maintenues dans le nouveau schéma. Et, si vous avez des exigences d'audit sur les données, vous devez être en mesure d'expliquer pourquoi elles sont organisées différemment et de faire correspondre les données pré-refoctor avec les données post-refactor. De plus, aucune de vos anciennes sauvegardes ne correspondra au nouveau schéma, ce qui représente un autre risque.
Des trucs effrayants.
la source
Il y a une frontière fine entre passer beaucoup de temps à sur-concevoir et investir un peu de votre temps pour ajouter juste assez de fonctionnalités pour vous faire gagner beaucoup de temps à l'avenir.
la source
Je pense que la théorie est que si vous incluez une table de liens pour prendre en charge une relation plusieurs à plusieurs entre 2 tables, alors même si vraiment seulement plusieurs relations à un existent dans les données, tout le monde écrira le SQL de telle sorte que si jamais un plusieurs à plusieurs est pris en charge tout fonctionnera "tout simplement".
Dans la pratique, je n'ai pas l'habitude de constater que cela est vrai, mais je suppose que le SQL est plus proche de ce qu'il doit être pour prendre en charge le plusieurs à plusieurs qu'il ne l'aurait été autrement.
Mais pour répondre précisément à votre question, il y a en fait beaucoup de peine à convertir une relation de 1 à plusieurs en plusieurs à plusieurs. La raison en est que SQL n'est pas conçu avec les mêmes types d'objectifs d'encapsulation que les objets, et la plupart des requêtes utilisent plus de tables sur la couche de base de données que les gens ne seraient à l'aise avec la visibilité d'un objet dans la couche métier.
Par conséquent, la modification d'une relation plusieurs à plusieurs affectera chaque requête impliquant les 2 tables d'origine, souvent un effet de cascade beaucoup plus large que celui qui se produira sur la couche métier. Donc, les gens mettent tout en œuvre pour empêcher que cela se produise.
À mon humble avis, cela ne serait pas nécessaire si nous avions un meilleur langage que SQL pour spécifier l'algèbre relationnelle. S'il était possible de créer une requête SQL pièce par pièce par des objets qui n'avaient pas besoin de visibilité pour chaque table de la requête, cela ne se produirait pas. Des choses comme LINQ (pour SQL ou pour les entités) tentent de résoudre ce problème, mais c'est une solution très complexe et difficile à optimiser (et je suis allé dans des groupes d'utilisateurs DBA où LINQ est mentionné et un grognement collectif monte à chaque fois). Je rêve d'un langage de base de données universellement pris en charge avec des fonctions d'algèbre relationnelle de première classe ...
En attendant, oui, vous pouvez refactoriser de 1 à plusieurs à plusieurs à plusieurs, mais cela peut demander beaucoup de travail.
la source
Je l'explique généralement de cette façon aux PHB - le code est les murs et le toit, la base de données est le fondement.
Il est possible de déplacer les murs et de changer le toit. Changer la fondation autour nécessite beaucoup de creuser et de reconstruire les murs et le toit.
Ce que les développeurs inexpérimentés (et les professeurs d'université) disent qu'il s'agit de "suringénierie" est ce que les développeurs expérimentés appellent "l'épreuve du futur". Malgré ce que dit la spécification, vous savez ce qui changera probablement au cours de l'ALM ou où les problèmes de performances se produiront, vous devez donc commencer par structurer votre table.
Déployer des scripts de mise à jour sur les serveurs des clients est un projet non trivial et chacun des administrateurs de base de données des clients est partout, vous souhaitant tout vérifier. Certaines colonnes et tableaux supplémentaires ne sont pas si mauvais après tout.
la source
La règle générale est que si une relation est un à un mais peut à l'avenir être plusieurs à plusieurs, elle devient alors plusieurs à plusieurs.
L'employé / service est un exemple classique. Dans la plupart des petites entreprises, il s'agit généralement d'une relation un à plusieurs la plupart du temps . Cependant, il y a presque toujours une situation où cela devient plusieurs à plusieurs - l'un de vos ingénieurs prend la direction, mais il est toujours responsable du support d'un produit qu'il a développé pendant qu'il était ingénieur, ou l'un de vos vendeurs a déménagé le développement de produits, mais, comme il a une relation étroite avec un client important, il est toujours le vendeur principal de ce client.
Cela ne coûte pas beaucoup plus si un à plusieurs est implémenté en plusieurs à plusieurs - mais la refactorisation d'une base de données et d'une application pour prendre en charge plusieurs à plusieurs est coûteuse et lourde de difficultés.
la source
Il existe deux façons d'envisager la conception d'un logiciel (et probablement bien d'autres choses) - une vue tactique ou une vue stratégique. Chacun a ses propres avantages et inconvénients.
Même avec les modifications du logiciel OO, c'est toujours une douleur, non seulement la partie codage est difficile, mais le processus de promotion d'un changement de production dans un environnement de réclamation (compte tenu de l'état actuel de la technologie) est irréel pour les grands systèmes qui sont censés être travailler 24/7.
Je suis mon principe qui dit: " Lorsque cela est possible, concevoir des artefacts logiciels partagés de manière stratégique " - Cela peut sembler aller à l'encontre du principe YAGNI d'une certaine manière, cependant, c'est mon avis. Cette approche garantit moins de retouches sur le coût de la complexité et des ressources.
Dans votre cas, les activités requises pour ajouter une nouvelle table de jonction incluraient: conception, approbation de conception, modification du schéma, réécriture de plusieurs méthodes pour CRUD pour 3 tables (à l'exception de certaines lectures), construction d'index, création d'une interface graphique pour le CRUD pour la nouvelle table, pour permettre à l'utilisateur de sélectionner les PK dans la création, la mise à jour de la nouvelle table, etc. Oh, et en passant, n'oubliez pas les tests unitaires, les tests d'acceptation des utilisateurs, les tests du système et la promotion de la production.
Si cela ne suffit pas, le vrai cauchemar vient de la perte d'informations. Si vous ne disposiez pas de la table de jonction au départ et que vous avez décidé de capturer les dates auxquelles l'association / la séparation entre un employé et un service s'est produite, vous ne pourrez pas remplir automatiquement la date sur la table de jonction. Vous devez les entrer manuellement (si vous avez les données).
Il est donc préférable de prévoir cela dès le départ.
la source
Comme Matthew l'a dit ci-dessus, la refactorisation / modification des bases de données est souvent plus impliquée que les logiciels, car la gestion des données doit également être prise en considération. Il existe des techniques qui peuvent vous aider, par exemple, à vous assurer que vous disposez d'une suite appropriée de tests unitaires de base de données, à dissocier les applications clientes de votre schéma de base en utilisant une 'API DB' - sprocs / vues, etc.
la source