Que ce soit pour créer des tableaux séparés pour différents types de produits?

25

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 ...

payling
la source
2
À ce point, je vous suggère de créer des feuilles de calcul qui imitent votre disposition de table et les remplissent de données. Cela exposera toutes les faiblesses qui pourraient exister.
Michael Riley - AKA Gunny
Comment allez-vous pointer des clés étrangères vers différents produits s'ils se trouvent dans des tables différentes? Lisez sur l'héritage de table s'il vous plaît.
Neil McGuigan

Réponses:

8

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

  • Créer une table parent qui contient uniquement les colonnes que tous les types partagent
  • Créez chaque type de produit comme sa propre table avec leurs colonnes individuelles, avec un extra: Un lien vers la table parent
  • Créez chaque table de «lien»: Product_Option, Model_option, etc. avec des liens vers les clés respectives.
  • Pour ceux qui ont des liens réciproques (MODEL_OPTION, OPTION_MODEL) allez-y et créez également ces tables. Cela ajoutera de la clarté dans vos jointures pour quiconque le regarde.

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.

Derek Downey
la source
5
Il n'y a plus que 4 types maintenant, mais qu'en est-il si d'autres sont ajoutés plus tard? Je suis sûr que le tableau principal des produits d'Amazon s'appelait à l'origine "Livres", mais pensez-vous qu'ils ont maintenant un tableau séparé pour chaque type de produit? Je ne pense pas que chaque type devrait avoir sa propre table, mais vous pouvez utiliser un modèle EAV pour des propriétés supplémentaires que chaque type pourrait avoir en commun.
Aaron Bertrand
1
@Aaron Fair point sur l'augmentation future des types de produits. Si ce scénario pouvait s'étendre à plus de 10 types de produits, je reconsidérerais. Mais je pense que les tableaux de produits spécifiques sont un choix de conception équitable pour une petite quantité de types de produits.
Derek Downey
1
Option C: une table de liens est-elle nécessaire? J'imagine que le Product_Option PK correspondrait au PK de la table Product et cela créerait l'association pour lier les deux tables.
payling
En utilisant Product_option comme exemple, le schéma serait (dans mon esprit): id, productID, optionID. productIDserait un FK à product.id, et optionIDest 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.
Derek Downey
OK, je comprends. J'ai mal lu ce que vous avez tapé .. Oups.
payling
7

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.

Mark Storey-Smith
la source
2

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.

Michael Riley - AKA Gunny
la source
Cette solution ressemble à l'option B (si je la comprends bien, ce que je ne suis pas sûr de faire). J'aurais une table principale (Produits) et une table "lien" (aka table adjacente / BillsofMaterials) pour créer les associations entre modèles, options, kits, etc. Est-ce correct?
payling
Je pense que le problème est assombri à cause des options. Permet de retirer les options de la discussion pendant un petit moment. Les pièces sont la plus petite unité. Un groupe de pièces constitue un modèle. Un groupe de pièces de rechange sous forme de kit constitue un sous-ensemble du modèle. Jusqu'ici tout va bien. Désormais, les pièces ont des options, supposons, pour des raisons de simplicité, qu'elles englobent deux catégories: la couleur (noir, rouge, chrome) et le matériau (métal, bois, plastique). Vous avez également mentionné que les modèles ont des options. Les options de modèle sont-elles distinctes des options de pièce ou les modèles ne semblent-ils avoir des options que parce que les pièces rendent les modèles différents?
Michael Riley - AKA Gunny
Les pièces n'ont pas "d'options" dans ma conception. Je définis l'option comme quelque chose qui va sur un modèle qui lui fournit des fonctionnalités étendues. Une option est composée de pièces. Un modèle peut avoir de nombreuses options différentes. Une option peut également convenir à de nombreux modèles différents.
payling
Ce n'est pas ainsi que vous avez formulé votre question. Citation: "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 ..." À ce point, je vous suggère créez des feuilles de calcul qui imitent votre disposition de tableau et remplissez-les de données. Cela exposera toutes les faiblesses qui pourraient exister.
Michael Riley - AKA Gunny
0

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.

Alan McBee
la source
Les champs nuls seraient minimes, car environ 75% des champs seraient utilisés dans chaque table. Je suppose que je suis plus préoccupé par les relations entre les types de produits. J'aurai environ trois tables de liens pointant vers la même table. Model_has_Option deux clés primaires, les deux identifiants de produit de la table de produits, si je devais utiliser une seule table pour représenter les types de produits. Je suis plus préoccupé si c'est la bonne chose à faire ou non.
payling
Bien que de nombreux facteurs affectent la «bonne» décision, il y a deux grands facteurs à considérer. 1: exigences de performance globales; 2: adaptabilité / complexité / maintenabilité. L'un de ces deux est probablement un peu plus important que l'autre. Si vous avez besoin de vitesse, dénormalisez en vous en tenant à l'option A. Vous aurez la duplication; c'est prévu. Si vous avez besoin de jouer avec le schéma régulièrement et que la vitesse n'est pas LE facteur le plus important, alors l'option B. Vous le faites "bien" en connaissant vos priorités, pas en adhérant aux "meilleures pratiques de quelqu'un d'autre".
Alan McBee