Comment concevoir une table de produits pour de nombreux types de produits où chaque produit a de nombreux parameters

Je n’ai pas beaucoup d’expérience dans la conception de tables. Mon objective est de créer une ou plusieurs tables de produits répondant aux exigences ci-dessous:

Comment puis-je répondre à ces exigences sans un tableau distinct pour chaque type de produit?

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

  • Héritage de table unique : une table pour tous les types de produit, avec suffisamment de colonnes pour stocker tous les atsortingbuts de tous les types. Cela signifie beaucoup de colonnes, dont la plupart sont NULL sur une ligne donnée.

  • Héritage de tableau de classes : un tableau pour les produits, qui stocke des atsortingbuts communs à tous les types de produits. Ensuite, un tableau par type de produit, stockant les atsortingbuts spécifiques à ce type de produit.

  • Héritage de table en béton : pas de table pour les atsortingbuts communs des produits. Au lieu de cela, une table par type de produit, stockant à la fois les atsortingbuts communs du produit et les atsortingbuts spécifiques au produit.

  • Sérialisé LOB : Une table pour les produits, stockant des atsortingbuts communs à tous les types de produits. Une colonne supplémentaire stocke un BLOB de données semi-structurées, en XML, YAML, JSON ou dans un autre format. Ce BLOB vous permet de stocker les atsortingbuts spécifiques à chaque type de produit. Vous pouvez utiliser des motifs de conception sophistiqués pour décrire cela, tels que Facade et Memento. Mais indépendamment du fait que vous ayez un tas d’atsortingbuts qui ne peuvent pas être facilement interrogés dans SQL; vous devez récupérer le blob complet dans l’application et le sortinger.

  • Entity-Atsortingbute-Value : Une table pour les produits et une table qui fait pivoter les atsortingbuts vers les lignes au lieu des colonnes. L’EAV n’est pas une conception valide par rapport au paradigme relationnel, mais de nombreuses personnes l’utilisent quand même. Ceci est le “modèle de propriétés” mentionné par une autre réponse. Voir d’autres questions avec le tag eav sur StackOverflow pour certains des pièges.

J’en ai écrit plus dans une présentation, Extensible Data Modeling .


Réflexions supplémentaires sur l’EAV: Bien que beaucoup de gens semblent préférer l’EAV, ce n’est pas le cas. Cela semble être la solution la plus flexible, et donc la meilleure. Cependant, gardez à l’esprit l’adage TANSTAAFL . Voici quelques inconvénients de l’EAV:

  • Pas de moyen de rendre une colonne obligatoire (équivalent de NOT NULL ).
  • Aucun moyen d’utiliser des types de données SQL pour valider des entrées.
  • Aucun moyen de s’assurer que les noms d’atsortingbut sont orthographiés de manière cohérente.
  • Pas moyen de mettre une clé étrangère sur les valeurs d’un atsortingbut donné, par exemple pour une table de consultation.
  • La récupération des résultats dans une présentation tabulaire classique est complexe et coûteuse, car pour obtenir des atsortingbuts à partir de plusieurs lignes, vous devez effectuer une JOIN pour chaque atsortingbut.

Le degré de flexibilité que vous offre EAV exige des sacrifices dans d’autres domaines, rendant probablement votre code aussi complexe (ou pire) qu’il ne l’aurait été pour résoudre le problème initial de manière plus conventionnelle.

Et dans la plupart des cas, il est inutile d’avoir ce degré de flexibilité. Dans la question sur les types de produit du PO, il est beaucoup plus simple de créer une table par type de produit pour les atsortingbuts spécifiques au produit. Vous disposez donc d’une structure cohérente au moins pour les entrées du même type de produit.

Je n’utiliserais EAV que si chaque ligne doit avoir un ensemble d’atsortingbuts distinct. Lorsque vous avez un ensemble fini de types de produits, EAV est excessif. Héritage de table de classe serait mon premier choix.

@Cœur de pierre

Je voudrais aller ici avec EAV et MVC tout le chemin.

@Bill Karvin

Voici quelques inconvénients de l’EAV:

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

pour une table de consultation.

Toutes les choses que vous avez mentionnées ici:

  • la validation des données
  • noms d’atsortingbuts validation d’orthographe
  • colonnes / champs obligatoires
  • gérer la destruction des atsortingbuts dépendants

à mon avis, n’appartient pas du tout à une firebase database car aucune des bases de données n’est capable de gérer ces interactions et ces exigences à un niveau approprié en tant que langage de programmation d’une application.

À mon avis, utiliser une firebase database de cette manière, c’est comme utiliser une pierre pour marteler un clou. Vous pouvez le faire avec un rocher, mais n’êtes-vous pas censé utiliser un marteau plus précis et spécifiquement conçu pour ce type d’activité?

La récupération des résultats dans une présentation tabulaire classique est complexe et coûteuse, car pour obtenir des atsortingbuts à partir de plusieurs lignes, vous devez effectuer une jointure pour chaque atsortingbut.

Ce problème peut être résolu en effectuant quelques requêtes sur des données partielles et en les traitant sous forme de tableau avec votre application. Même si vous disposez de 600 Go de données produit, vous pouvez les traiter par lots si vous avez besoin de données provenant de chaque ligne de ce tableau.

Aller plus loin Si vous souhaitez améliorer les performances des requêtes, vous pouvez sélectionner certaines opérations telles que la génération de rapports ou la recherche de texte globale et préparer des tables d’index qui stockeront les données requirejses et seront régénérées périodiquement, disons toutes les 30 minutes.

Vous n’avez même pas besoin de vous préoccuper du coût du stockage de données supplémentaire, car il devient moins cher et moins cher chaque jour.

Si vous êtes toujours préoccupé par les performances des opérations effectuées par l’application, vous pouvez toujours utiliser Erlang, C ++, Go Language pour pré-traiter les données et traiter ensuite les données optimisées dans votre application principale.

Si j’utilise l’ Class Table Inheritance signifie:

un tableau pour les produits, stockant les atsortingbuts communs à tous les types de produits. Ensuite, un tableau par type de produit, stockant les atsortingbuts spécifiques à ce type de produit. -Bill Karwin

Ce que j’aime le mieux des suggestions de Bill Karwin. Je peux en quelque sorte prévoir un inconvénient, que je vais essayer d’expliquer comment éviter de devenir un problème.

Quel plan d’urgence doit-on mettre en place lorsqu’un atsortingbut commun à 1 type devient commun à 2, puis 3, etc.?

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

Si nous vendons des meubles, nous pourrions vendre des chaises, des lampes, des canapés, des téléviseurs, etc. Le type de téléviseur pourrait être le seul que nous ayons à avoir une consommation élecsortingque. Je mettrais donc l’atsortingbut power_consumption sur le tv_type_table . Mais nous commençons alors à transporter des systèmes de cinéma à domicile qui ont également une propriété power_consumption . OK, c’est juste un autre produit, donc je vais append ce champ à la stereo_type_table car cela est probablement plus facile à ce stade. Mais au fil du temps, alors que nous commençons à transporter de plus en plus d’électronique, nous réalisons que power_consumption est assez large pour qu’il soit dans la main_product_table . Qu’est-ce que je devrais faire maintenant?

Ajoutez le champ à la main_product_table . Ecrivez un script pour parcourir l’électronique et mettez la valeur correcte de chaque type_table à main_product_table . Puis déposez cette colonne de chaque type_table .

Maintenant, si j’utilisais toujours la même classe GetProductData pour interagir avec la firebase database pour extraire les informations du produit; alors, si des modifications du code doivent maintenant être refactorisées, elles ne doivent concerner que cette classe.

Vous pouvez avoir une table Product et une table ProductAdditionInfo séparée avec 3 colonnes: ID du produit, nom de l’info supplémentaire, valeur d’information supplémentaire. Si la couleur est utilisée par de nombreux produits, mais pas tous, vous pouvez la définir comme colonne nullable dans la table Product ou simplement la placer dans ProductAdditionalInfo.

Cette approche n’est pas une technique traditionnelle pour une firebase database relationnelle, mais je l’ai vu beaucoup utilisée dans la pratique. Il peut être flexible et avoir de bonnes performances.

Steve Yegge appelle cela le modèle Propriétés et a écrit un long article sur son utilisation.