Je suis en train de concevoir une base de données et j'ai des doutes sur mes décisions de conception initiales ...
Les types de produits sont les suivants ... Modèles, pièces, kits de pièces de rechange et options.
Option A (première conception): je prévoyais d'avoir des tableaux séparés pour les types de produits ci-dessus. Je dirais qu'environ 75% des champs seraient les mêmes dans chaque table.
J'ai créé chaque type de produit sous forme de tableaux séparés en raison des associations que je dois créer entre eux. Par exemple, un modèle peut avoir de nombreuses options et une option peut avoir de nombreux modèles. Une option peut également avoir de nombreuses pièces et une pièce peut avoir de nombreuses options ... et ainsi de suite ...
Option B: Au lieu d'avoir des tableaux séparés, je pourrais créer un tableau appelé Produit qui comprend le modèle, la pièce, les kits de pièces de rechange et les options. Je pourrais avoir un champ appelé type pour différencier le modèle, les options, etc. Je suppose qu'un inconvénient est que plusieurs champs ne seraient jamais utilisés (laissés nuls) pour certains types de produits. J'imagine que c'est là que «les meilleures pratiques» entrent en jeu.
L'option B réduirait considérablement la complexité de la conception de la base de données. Je n'aurais pas non plus à me soucier de référencer un tas de tableaux lors de l'extraction de données pour les requêtes ...
Réponses:
Si c'était ma décision de conception, j'irais probablement avec plus d'une «Option C» (option modifiée a).
Tout d'abord, pourquoi ne pas 'Option B':
D'une part, j'aime la clarté que chaque produit a sa propre table. S'il s'agit d'une seule grande table avec un champ pour déterminer le type, la relation n'est pas aussi claire.
Pour un autre, la stratégie d'indexation exigerait toujours que ce champ de type soit répertorié. Comme il ne s'agit que de 4 types, la cardinalité d'index est extrêmement faible (
SELECT * FROM product_table WHERE type='X'
fait en fait une analyse complète de la table de toute façon)Option C
L'inconvénient est la complexité de s'assurer d'éviter les orphelins lorsque les choses sont mises à jour / supprimées, et de concevoir initialement les requêtes qui utilisent ces tables.
la source
productID
serait un FK àproduct.id
, etoptionID
est un FK àoption.id
. C'est ce que je voulais dire par table de liens. Et oui, il est nécessaire dans cette conception de permettre à un seul produit de se lier à plusieurs options.Je vous suggère de commencer par le modèle relationnel "correct", votre option A. Si l'utilisation typique de ce modèle vous conduit vers la dénormalisation dans certains domaines, n'ayez pas peur de le faire.
La semaine dernière, j'ai discuté avec un collègue de la façon dont les conceptions de schéma sont souvent considérées comme quelque chose qui est gravé dans la pierre et ne peut jamais changer. Étrange, compte tenu du fait que la refactorisation est dans la pratique acceptée dans toutes les autres couches d'une application, cette refactorisation d'un schéma de base de données est toujours considérée comme peu pratique.
Si l'interface avec la base de données est bien conçue, rien ne vous empêche d'adapter le schéma à mesure que vous en apprenez davantage sur les modèles d'utilisation des systèmes.
la source
Cela ressemble beaucoup à l' héritage de nomenclatures / cardinalités multiples que Paul Neilsen décrit dans le chapitre 17 de la Bible SQL Server 2008 .
Le chapitre entier est une très bonne lecture et la section spécifique qui traite de votre problème plusieurs-à-plusieurs se trouve aux pages 416-419.
C'est la meilleure discussion que j'ai vue concernant le type de pièces éclatées de conception de données.
la source
Si vous pouvez imaginer un scénario probable où il y aurait des requêtes fréquentes qui couvrent les quatre types de produits (et cela me semble probable), alors votre option B est la meilleure.
Au lieu de laisser un grand nombre de champs Nullable inutilisés dans la table Product, pourquoi ne pas ajouter une table ModelProduct, une table PartProduct, une table ReplacementPartKitProduct et avoir uniquement les champs distincts pour ces types dans ces tables? Utilisez la même clé primaire sur ces tables que votre table de produit. Rejoignez la table Product et ModelProduct lorsque vous souhaitez travailler avec des modèles. Besoin de déterminer si la fiche produit que vous avez est une pièce? Effectuez simplement une jointure gauche de Product vers PartProduct, et si le PartProduct. [PrimaryKey] n'est pas nul, vous avez une pièce. S'il est nul, ce n'est pas une pièce. Vous pouvez également ajouter un champ ProductType à la table Product.
la source