Comment concevoir une table de produits pour de nombreux types de produits où chaque produit a de nombreux paramètres

StackOverflow https://stackoverflow.com/questions/695752

Question

Je n'ai pas beaucoup d'expérience dans la conception de la table. Mon but est de créer une ou plusieurs tables qui satisfont aux exigences ci-dessous:

  • soutien de nombreux types de produits (TV, téléphone, PC, ...). Chaque type de produit a un ensemble de paramètres différents, comme:

    • Téléphone aura couleur, taille, poids, OS ...

    • PC aura CPU, disque dur, RAM ...

  • L'ensemble des paramètres doit être dynamique. Vous pouvez ajouter ou modifier un paramètre que vous voulez.

Comment puis-je répondre à ces exigences sans une table distincte pour chaque type de produit?

Était-ce utile?

La solution

Vous avez au moins ces cinq options pour la modélisation de la hiérarchie de type que vous décrivez:

  • unique Héritage de Table : une table pour tous les types de produits, avec des colonnes assez pour stocker tous les attributs de tous les types. Cela signifie beaucoup de colonnes, dont la plupart sont NULL sur une ligne donnée.

  • classe héritage de table : une table pour les produits, le stockage des attributs communs à tous les produits les types. Ensuite, une table par type de produit, le stockage des attributs spécifiques à ce type de produit.

  • béton Table Héritage : pas de table pour les produits communs attributs. Au lieu de cela, une table par type de produit, stocker à la fois les attributs des produits communs et des attributs des produits spécifiques.

  • LOB en feuilleton: Une table pour les produits, le stockage des attributs communs à tous les types de produits . Une colonne stocke supplémentaires un BLOB de données semi-structurées, en XML, YAML, JSON, ou un autre format. Cette blob vous permet de stocker les attributs spécifiques à chaque type de produit. Vous pouvez utiliser des modèles de conception de fantaisie pour décrire ce, comme façade et Memento. Mais quelle que soit vous avez un blob d'attributs qui ne peuvent pas être facilement interrogeables dans SQL; vous devez chercher le blob tout à l'application et le tri là-bas.

  • Entité-Attribut Valeur : Une table pour les produits, et une table qui fait pivoter les attributs de lignes, au lieu de colonnes. EAV n'est pas une conception valable par rapport au paradigme relationnel, mais beaucoup de gens l'utilisent de toute façon. Ceci est le « modèle Propriétés » mentionné par une autre réponse. Voir d'autres questions avec le tag EAV sur StackOverflow pour certains des pièges.

Je l'ai écrit plus à ce sujet dans une présentation, Extensible Modélisation des données .


pensées supplémentaires sur EAV: Bien que beaucoup de gens semblent favoriser EAV, je ne sais pas. Il semble que la solution la plus flexible, et donc le meilleur. Cependant, gardez à l'esprit l'adage TANSTAAFL . Voici quelques-uns des inconvénients de EAV:

  • Pas moyen de faire une colonne obligatoire (équivalent de NOT NULL).
  • aucun moyen d'utiliser les types de données SQL pour valider les entrées.
  • Pas moyen de faire en sorte que les noms d'attributs sont toujours orthographié.
  • Pas moyen de mettre une clé étrangère sur les valeurs d'un attribut donné, par exemple pour une table de consultation.
  • Récupérer des résultats dans une mise en page de tableau classique est complexe et coûteux, car pour obtenir les attributs de plusieurs lignes que vous devez faire JOIN pour chaque attribut.

Le degré de flexibilité EAV vous donne exige des sacrifices dans d'autres domaines, ce qui rend probablement votre code aussi complexe (ou pire) que cela aurait été de résoudre le problème d'origine d'une manière plus conventionnelle.

Dans la plupart des cas, il est inutile d'avoir ce degré de flexibilité. Dans la question OP sur les types de produits, il est beaucoup plus simple de créer une table par type de produit pour les attributs spécifiques à un produit, vous avez donc une structure cohérente appliquée au moins pour les entrées du même type de produit.

J'utilise EAV seulement si chaque ligne doit être autorisé à potentiellement avoir un ensemble distinct d'attributs. Lorsque vous avez un ensemble fini de types de produits, EAV est surpuissant. L'héritage de classe table serait mon premier choix.


Mise à jour 2019: Plus je vois des gens en utilisant JSON comme une solution pour le problème « de nombreux attributs personnalisés », moins j'aime cette solution. Il fait des requêtes trop complexes, même en utilisant fonctions JSON pour les soutenir. Il faut beaucoup plus d'espace de stockage pour stocker des documents JSON, par rapport à stocker dans des lignes normales et des colonnes.

En fait, aucune de ces solutions sont faciles ou efficaces dans une base de données relationnelle. L'idée d'avoir « attributs variables » est fondamentalement en contradiction avec la théorie relationnelle.

Qu'est-ce qu'il revient à dire que vous devez choisir une des solutions basées sur ce qui est le moins mauvais pour votre app. Par conséquent, vous devez savoir comment vous allez interroger les données avant de choisir une conception de base de données. Il n'y a aucun moyen de choisir une solution qui est « meilleur », car l'une des solutions pourrait être préférable pour une application donnée.

Autres conseils

@StoneHeart

J'irais ici avec EAV et MVC tout le chemin.

Karvin @ Bill

  

Voici quelques-uns des inconvénients de   EAV:

No way to make a column mandatory (equivalent of NOT NULL).
No way to use SQL data types to validate entries.
No way to ensure that attribute names are spelled consistently.
No way to put a foreign key on the values of any given attribute, e.g.
     

pour une table de consultation.

Toutes ces choses que vous avez mentionnées ici:

  • validation de données
  • les noms d'attribut validation d'orthographe
  • colonnes obligatoires / champs
  • manipulation de la destruction des attributs dépendants

à mon avis, ne font pas partie d'une base de données du tout, car aucune des bases de données sont capables de gérer ces interactions et les exigences d'un niveau approprié en tant que langage de programmation d'une application fait.

À mon avis en utilisant une base de données de cette manière est comme utiliser un rocher pour enfoncer un clou. Vous pouvez le faire avec une pierre, mais n'êtes-vous pas supposer d'utiliser un marteau qui est plus précis et spécialement conçu pour ce genre d'activité?

  

Des résultats encourageants dans une mise en page de tableau classique est complexe et   coûteux, parce que pour obtenir les attributs   à partir de plusieurs lignes que vous devez faire JOIN   pour chaque attribut.

Ce problème peut être résolu en faisant quelques requêtes sur des données partielles et de les traiter dans la mise en page sous forme de tableau avec votre application. Même si vous avez des données 600GB produit vous pouvez le traiter par lots si vous avez besoin des données de chaque ligne unique dans ce tableau.

Pour aller plus loin Si vous souhaitez améliorer les performances des requêtes, vous pouvez sélectionner certaines opérations comme par exemple rapports ou recherche de texte global et préparer les tables d'index qui stockent des données nécessaires et seraient régénérés périodiquement, permet de dire toutes les 30 minutes.

Vous ne devez même pas se soucier du coût du stockage de données supplémentaires, car il devient chaque jour moins cher et moins cher.

Si vous encore être concernés par la performance des opérations effectuées par l'application, vous pouvez toujours utiliser Erlang, C ++, Go Langue de pré-traiter les données et plus tard traiter uniquement les données optimisées plus loin dans votre application principale.

Si je sens Class Table Inheritance:

  

une table pour les produits, le stockage des attributs communs à tous les types de produits. Ensuite, une table par type de produit, le stockage des attributs spécifiques à ce type de produit.   -Bill Karwin

Ce qui me plaît le meilleur des suggestions de Bill Karwin .. Je peux prévoir un genre d'inconvénient, que je vais essayer d'expliquer comment empêcher de devenir un problème.

Quel plan d'urgence dois-je avoir en place quand un attribut qui est commun à seulement 1 type devient alors commune à 2, puis 3, etc?

Par exemple: (ce qui est juste un exemple, pas mon vrai problème)

Si nous vendons des meubles, nous pouvons vendre des chaises, lampes, canapés, téléviseurs, etc. Le type de télévision pourrait être le seul type que nous transporter qui a une consommation d'énergie. Donc, je mettrais l'attribut power_consumption sur le tv_type_table. Mais nous commençons à réaliser des systèmes de cinéma maison qui ont également une propriété power_consumption. OK est juste un autre produit donc je vais ajouter ce champ à la stereo_type_table et puisque c'est probablement plus facile à ce stade. Mais au fil du temps que nous commençons à réaliser de plus en plus d'électronique, nous nous rendons compte que power_consumption est assez large qu'il devrait être dans le main_product_table. Que dois-je faire maintenant?

Ajoutez le champ à la main_product_table. Ecrire un script à boucle à travers l'électronique et de mettre la valeur correcte de chaque type_table au main_product_table. Puis déposez cette colonne de chaque type_table.

Si j'utilise toujours la même classe GetProductData pour interagir avec la base de données pour tirer la fiche technique; alors si des changements dans le code maintenant besoin refactoring, ils devraient être à cette classe uniquement.

Vous pouvez avoir une table de produit et une table ProductAdditionInfo séparée avec 3 colonnes: ID de produit, le nom d'information supplémentaire, la valeur d'information supplémentaire. Si la couleur est utilisé par beaucoup, mais pas tous les types de produits que vous auriez pu être une colonne nullable dans la table de produit, ou mettez simplement dans ProductAdditionalInfo.

Cette approche n'est pas une technique traditionnelle pour une base de données relationnelle, mais je l'ai vu beaucoup utilisé dans la pratique. Il peut être flexible et avoir une bonne performance.

Steve Yegge appelle cette le motif Propriétés et a écrit un long message à l'utiliser.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top