2017-04-05 1 views
1

J'essaie de comprendre quand inclure plusieurs clés étrangères dans une table par rapport à quand utiliser des tables associatives.Quand utiliser plusieurs clés étrangères dans une seule table par rapport aux tables associatives?

Modifier: Ajouté a diagram pour faciliter la compréhension.

J'ai un système de paramètres que de nombreux paramètres sont spécifiques à une division ou une classification. Ainsi, par exemple, un paramètre comme "nombre par équipe" peut être différent dans la division 1, classe A que dans la division 3, classe A. Et le "score minimum" peut être différent dans la division 1, classe A que dans la division 1, classe C. Évidemment, il y a aussi des paramètres qui n'ont rien à voir avec une division ou une classification que je pense devoir être dans le même tableau.

Donc, une façon que je pourrais faire est de simplement placer les ID div/class comme FK dans la table de paramètres. Ensuite, tous les paramètres qui ne dépendent pas de l'un ou l'autre (ou l'un ou l'autre) seraient NULL pour ces ID.

divisions 
---------- 
id (int) 
label (varchar) 
description (varchar) 

classification 
-------------- 
id (int) 
label (varchar) 
description (varchar) 

settings 
--------- 
id (int) 
division_id (int) (FK) 
class_id (int) (FK) 
key (varchar) 
value (varchar) 

Puisqu'il n'y aurait jamais qu'une seule combinaison de clé de division, de classification et de paramètres, cela devrait fonctionner, n'est-ce pas? Mais cela «se sent» mal en quelque sorte - presque comme mettre les différents événements en compétition dans la table des concurrents. Je ne peux pas non plus garantir qu'ils ne proposeront pas de catégories/types supplémentaires pour lesquels ils souhaiteraient appliquer des paramètres ultérieurement. Donc, cela me donne envie de faire quelque chose comme:

divisions 
---------- 
id (int) 
label (varchar) 
description (varchar) 

classifications 
-------------- 
id (int) 
label (varchar) 
description (varchar) 

settings 
--------- 
id (int) 
key (varchar) 
value (varchar) 

settings_to_divisions 
------------------------- 
setting_id (int) 
division_id (int) 

settings_to_classifications 
------------------------------ 
setting_id (int) 
class_id (int) 

Je pense que cela permettrait une croissance plus facile quand ils viennent avec une nouvelle catégorie (il suffit de créer « catégories » et une « tables settings_to_categories »). Mais alors j'aurais probablement un ensemble d'enregistrements presque dupliqués dans la table de paramètres ([id], "min_score", 5) et plusieurs tables presque identiques (id, label, description) pour les éléments associés - tout juste pour créer un enregistrement de paramètre unique. Alors que se passe-t-il quand ils disent vouloir des réglages différents pour les hommes et les femmes? Dois-je simplement ajouter un champ supplémentaire dans la table des paramètres et coder en dur les chaînes 'Homme' et 'Femme' dans l'enregistrement, null partout sauf pour les paramètres qui sont spécifiques au genre? Ou à l'autre bout des choses, créez une table 'gender' séparée avec seulement 2 enregistrements et utilisez-la aussi dans la table user? Tout à coup, je suis à:

divisions 
--------- 
id (int) 
label (varchar) 
description (varchar) 

classifications 
--------------- 
id (int) 
label (varchar) 
description (varchar) 

categories 
---------- 
id (int) 
label (varchar) 
description (varchar) 

type 
---- 
id (int) 
label (varchar) 
description (varchar) 

gender 
------ 
id (int) 
label (varchar) 
description (varchar) 

settings 
--------- 
id (int) 
key (varchar) 
value (varchar) 

settings_to_divisions 
--------------------- 
setting_id (int) 
division_id (int) 

settings_to_classifications 
--------------------------- 
setting_id (int) 
class_id (int) 

settings_to_categories 
---------------------- 
setting_id (int) 
category_id (int) 

settings_to_type 
---------------- 
setting_id (int) 
type_id (int) 

settings_to_gender 
------------------ 
setting_id (int) 
gender_id (int) 

Il commence à se sentir presque ... trop normalisée. Même si c'est juste moi. J'essaye juste de concevoir ceci intelligemment de sorte que même si certains paramètres s'appliquent à tous les joueurs de Division 3, quand ils me disent qu'ils ont besoin d'autres catégories et que l'application devrait se comporter différemment pour Division 3, Classe A, Catégorie Vert, Rogue, Joueurs masculins vs Joueurs féminins, je n'ai pas besoin de reconcevoir ma base de données ou mon application pour obtenir/définir facilement ce que ce paramètre différent devrait être. Je suis sûr que ce n'est pas un nouveau concept. Cela doit être un modèle de conception reconnu quelque part, mais il est difficile de chercher des méthodes et des approches pour gérer une situation où vous pourriez avoir 3 (ou 5 ou 8) différentes façons d'associer une seule entité de base de données.

Je suis actuellement penché vers l'approche table d'association (normalisation significative), mais je ne suis pas vraiment un DBA. Alors je fais une décision de conception stupide? Quels seraient les aspects négatifs/défis de cette approche? Une approche encore différente serait-elle meilleure?

Répondre

0

Ce poste est un peu vieux, mais je vais quand même répondre aux futurs lecteurs:

La réponse est simple: utiliser l'approche 1

La seule raison pour laquelle vous auriez besoin d'une table entre les divisions/classification est d'associer un réglage unique avec plusieurs divisions/enregistrements de classification.

Je peux vous dire par expérience que vous ne voulez pas cela. En utilisant le même réglage encore et encore, vous aurez l'impression d'avoir un mécanisme d'économie de temps et d'espace, mais vous le regretterez à l'avenir. La seconde vous devez créer un nouveau paramètre pour un sous-ensemble d'enregistrements associé à un seul paramètre ou, pire, vous devrez modifier la table de paramètres qui force une grande majorité des enregistrements à associer un seul enregistrement de division/classification à un seul réglage - vous détester votre vie. Deuxièmement, la création d'une table de paramètres où les paramètres sont des chaînes de texte est très flexible mais pas trop efficace. Si vous avez plusieurs paramètres pour une seule division/classification, votre application doit parcourir les résultats en effectuant des instructions if sur chaque enregistrement.

L'alternative, bien sûr, est de créer une colonne pour chaque paramètre. Cela aussi peut être un point douloureux que les nouveaux paramètres nécessitent un déploiement. Cependant, si un bon nombre de paramètres sont booléens, vous pouvez obtenir des gains de performances significatifs mais en utilisant des valeurs BIT.

Exemple:

Si vous avez 6 champs de bits, le moteur de base de données doit comparer un seul octet des données/enregistrement pour trouver la valeur nécessaire - par rapport à la recherche sur le texte qui doit comparer plusieurs octets sur plusieurs enregistrements. Enfin, si le nombre de paramètres augmente considérablement à l'avenir, les performances peuvent être affectées à l'aide de chaînes de texte.