table unique avec colonnes supplémentaires par rapport à plusieurs tables qui dupliquent le schéma


13

Je travaille sur un projet où, à un moment donné, je devais décider si, dans la base de données, je devrais avoir une seule table avec plusieurs colonnes que tous les enregistrements n'utilisent pas, ou plusieurs tables avec un schéma dupliqué.

Je crée une application d'informations sportives qui peut gérer plusieurs sports. Nous pouvons gérer la NBA, la NHL, la MLB, la NFL par exemple. Chaque sport a des concepts très similaires - Équipes, horaires, blessures, informations sur les joueurs.

Bien entendu, notre source de données ne nous donne pas chaque donnée dans le même schéma. Chaque sport a un schéma différent auquel nous recevons des données de notre fournisseur.

Parce qu'il n'y avait pas assez de temps (demandes des clients) pour effectuer une analyse initiale des flux de données afin de déterminer les points communs, j'ai couvert mon pari et pris le `` pari sûr '' et créé des tableaux individuels séparés pour chaque sport au lieu d'un ensemble de tableaux que tous sports utilisés.

Le résultat est un schéma dupliqué dans plusieurs des tables, et donc des interfaces dupliquées avec la base de données (par exemple des procs stockés) également. J'ai quelque chose comme NBA_Game, NFL_Game, NBA_Team, NFL_Team, etc. chaque table peut avoir quelques propriétés que l'autre n'a pas, et plusieurs qui sont partagées. cela continue pour disons 5-10 tables à travers 4 ou 5 sports. Je ne suis toujours pas sûr que ce soit entièrement une mauvaise chose - l'alternative, ayant un seul ensemble de tables qui avait des propriétés que tous les sports n'utiliseraient pas, aurait peut-être aussi été difficile à manier.

Quelqu'un qui a fait cela a-t-il rencontré des pièges de ce type de conception et pourrait partager son expérience ici? Des choses qui pourraient m'aider à savoir maintenant au lieu d'apprendre à la dure sur la route? L'avez-vous fait dans l'autre sens, en ayant une grande table / un ensemble de tables, avec des colonnes que tous les enregistrements n'utiliseraient pas? Quels pièges avez-vous rencontrés en faisant cela?

Y a-t-il une alternative telle que l' héritage de table que vous avez utilisé dans le passé qui fonctionnait mieux?

Merci

Réponses:


12

En fin de compte, cela se résume à l'utilisation et à l'architecture.

Architecture

Le système gère-t-il "n'importe quel sport"? L'idée est-elle de mettre votre chapeau d'astronaute d'architecture et de construire un système générique capable de gérer tout type de sport futur qui n'existerait peut-être même pas aujourd'hui?

Si c'est le cas, avoir des tables nommées dynamiquement est évidemment une énorme douleur, il serait donc logique d'avoir un schéma qui prend en charge n sports, si nécessaire.

Cela dit, j'ai un parti pris très fort contre cette approche: c'est presque toujours plus de travail et conduit à de moins bons résultats. La création d'une interface utilisateur, d'un schéma, etc. distincts pour chaque sport mènera finalement à une meilleure expérience utilisateur et à une gestion plus facile du code, même si cela signifie une certaine quantité superficielle de duplication (comment éviter / minimiser cela est une question distincte).

Comment gérez-vous les joueurs qui pratiquent plusieurs sports? Ont-ils deux entrées (par exemple, vous traitez comme des personnes différentes) ou essayez-vous de faire quelque chose de spécifique avec eux?

Utilisation

Supposons donc que vous ne fassiez pas de sport de manière dynamique (par exemple, si quelqu'un veut ajouter un nouveau sport, il faut un effort de développement pour l'ajouter).

Y a-t-il déjà eu un moment où vous montrez des joueurs (ou tout autre objet que vous avez mentionné) de plus d'un sport à la fois?

Je pourrais voir cela pour une fonction de recherche, où vous pouvez rechercher par nom de joueur ou d'équipe (quel que soit le sport), mais au-delà, je ne peux pas imaginer de nombreux cas d'utilisation.

Si vous n'avez jamais besoin de le faire, votre approche est parfaitement adaptée. Vous pouvez arrêter de lire ici.

Schémas alternatifs

Vues

Je suis fan de KISS. En plus de 15 ans de développement de logiciels, je continue de revenir à la philosophie "construire la chose la plus simple qui fonctionne".

Donc ma réaction initiale, en supposant qu'une fonction de recherche cross-sport est vraiment le seul cas d'utilisation, est de créer des vues:

SELECT PlayerName, 'NFL' as [Sport], TeamName FROM NFL_Players JOIN NFL_Teams ... 
UNION  
SELECT PlayerName, 'NHL' as [Sport], TeamName FROM NHL_Players JOIN NHL_Teams ... 
UNION ....

Bien sûr, si vous ajoutez un nouveau sport, vous devez ajouter à la vue. Il peut également être utile d'inclure d'autres informations courantes, mais cela dépend vraiment de ce qui doit être affiché.

J'essaierais de garder tous les éléments spécifiques au sport dans la définition de la vue, de sorte que le code de recherche n'a pas besoin d'avoir beaucoup ou de code spécifique (en plus de savoir peut-être comment créer un lien vers /nhl/players/player-namevs /nfl/...ou comment votre application le fait).

Héritage de table

L'héritage de table peut fonctionner, mais est assez complexe. Je n'ai pas une tonne d'expérience avec cela, et en fait, je pense que chaque fois que j'ai été impliqué dans l'évaluation, nous avons fini par faire quelque chose de plus simple (comme je le suggère ici).

Donc, personnellement, je n'ai pas encore trouvé pourquoi cela serait utile, mais il y a peut-être un cas d'utilisation convaincant (que je ne connais pas) qui justifie la complexité (par exemple, l'héritage de table résout le cas d'utilisation mieux que toute autre solution) .

Tableaux séparés pour les attributs spécifiques au sport

Vous pouvez faire une seule playerstable qui a des attributs communs à tous les joueurs de tous les sports, puis un autre ensemble de tables comme nhl_players_detailscelui-ci contient un playerId et des colonnes avec des informations supplémentaires sur le joueur. S'il y a une tonne d'attributs communs, ou si vous avez de nombreuses utilisations de "tous les joueurs de tous les sports", cela peut avoir du sens.

Paires de valeurs clés pour les attributs spécifiques au sport

Approche complètement autre: un playerstableau (encore une fois, avec des attributs communs comme le nom), puis une player_datatable qui a PlayerId, Sport, Attribute, Value. Les noms d'attribut saisis seraient spécifiques au sport. Cela vous permet essentiellement d'ajouter de nouveaux attributs sans modifier le schéma (votre code devra encore savoir pour les charger / les afficher bien sûr). L'inconvénient est que vous perdez une certaine intégrité: la valeur serait généralement un champ de chaîne, donc votre code d'application devrait être résilient et gérer les échecs potentiels lors de la conversion de la chaîne valueen un type de données spécifique (comme un entier).

Ce concept peut bien sûr s'appliquer aux équipes, aux jeux, etc.


La recherche d'une solution à un projet existant nécessitera plusieurs types et tableaux authentifiables, la mention des vues ici, que j'avais oubliée, a vraiment aidé à offrir une autre solution possible à mes recherches. Je vous remercie.
FullStackFool

5

Vous parlez de normalisation de la base de données . Vous serez peut-être soulagé d'apprendre qu'il n'existe pas de modèle de données parfait et qu'une normalisation accrue n'est pas toujours meilleure. La normalisation peut imposer des coûts en termes de clarté du modèle de données et des performances de la base de données. Par conséquent, le meilleur modèle à sélectionner dépendra de vos besoins d'utilisation.

En surface, vos exemples semblent assez similaires dans le concept (X_Game vs Y_Game et X_Team vs Y_Team) que le surcoût supplémentaire de quelques colonnes ne semble pas déraisonnable. Cela dit, si chaque sport allait ajouter plusieurs dizaines de colonnes supplémentaires au tableau, ce serait en effet difficile à manier.

Dans ce cas, vous pouvez envisager un modèle hybride, où les données communes sont conservées dans une table centrale, mais les données spécifiques au sport sont conservées dans une structure de données liée. Quelque chose comme:

table Game {
    gameId int,
    teamId1 int fk,
    teamId2 int fk
}

table HockeyGame {
    gameId int fk,
    penaltyMinutes int
}

table BasketballGame {
    gameId int fk,
    freeThrows int
}

C'est ce que j'allais proposer, plus peut-être une colonne dans le tableau Game indiquant le type de jeu. Je me rends compte que cela peut être déduit en rejoignant les autres tables, mais si le nombre de types de jeux augmente, cela commence à devenir fastidieux.
Rory Hunter

Absolument - ce n'est qu'un modèle squelette pour illustrer les relations fondamentales et quelques exemples de ce qui pourrait être des données communes par rapport à des données spécifiques au sport.
Midnotion
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.