web-dev-qa-db-fra.com

Base de données de valeurs d'attribut d'entité par rapport au commerce électronique de modèle relationnel strict

Il est sûr de dire que le modèle de base de données EAV/CR est mauvais. Cela dit,

Question: Quel modèle, technique ou modèle de base de données utiliser pour traiter les "classes" d'attributs décrivant les produits de commerce électronique qui peuvent être modifiés au moment de l'exécution?

Dans une bonne base de données de commerce électronique, vous stockerez des classes d'options (comme la résolution TV, puis une résolution pour chaque téléviseur, mais le produit suivant peut ne pas être un téléviseur et ne pas avoir une "résolution TV"). Comment les stockez-vous, effectuez-vous une recherche efficace et permettez-vous à vos utilisateurs de configurer des types de produits avec des champs variables décrivant leurs produits? Si le moteur de recherche constate que les clients recherchent généralement des téléviseurs en fonction de la profondeur de la console, vous pouvez ajouter une profondeur de console à vos champs, puis ajouter une seule profondeur pour chaque type de produit de télévision au moment de l'exécution.

Il existe une caractéristique commune de Nice parmi les bonnes applications de commerce électronique où elles affichent un ensemble de produits, puis ont des menus latéraux "drill down" où vous pouvez voir "Résolution TV" en tant qu'en-tête, et les cinq résolutions TV les plus courantes pour le ensemble trouvé. Vous cliquez sur l'un et il n'affiche que les téléviseurs de cette résolution, ce qui vous permet d'approfondir davantage en sélectionnant d'autres catégories dans le menu latéral. Ces options seraient les attributs de produit dynamiques ajoutés au moment de l'exécution.

Discussion supplémentaire:

Donc, pour faire court, y a-t-il des liens sur Internet ou des descriptions de modèles qui pourraient "académiquement" corriger la configuration suivante? Je remercie Noel Kennedy d'avoir suggéré une table de catégories, mais le besoin peut être plus grand que cela. Je le décris d'une manière différente ci-dessous, en essayant de souligner la signification. J'ai peut-être besoin d'une correction du point de vue pour résoudre le problème, ou je vais peut-être devoir approfondir l'EAV/CR.

J'adore la réponse positive au modèle EAV/CR. Mes collègues développeurs disent tous ce que Jeffrey Kemp a abordé ci-dessous: "les nouvelles entités doivent être modélisées et conçues par un professionnel" (hors contexte, lisez sa réponse ci-dessous). Le problème est:

  • les entités ajoutent et suppriment des attributs chaque semaine
    (les mots-clés de recherche dictent les attributs futurs)
  • de nouvelles entités arrivent chaque semaine
    (les produits sont assemblés à partir de pièces)
  • les anciennes entités disparaissent chaque semaine
    (archivé, moins populaire, saisonnier)

Le client souhaite ajouter des attributs aux produits pour deux raisons:

  • département/recherche par mot clé/tableau de comparaison entre produits similaires
  • configuration des produits de consommation avant le paiement

Les attributs doivent avoir une signification, pas seulement une recherche par mot-clé. S'ils veulent comparer tous les gâteaux qui ont un "glaçage à la crème fouettée", ils peuvent cliquer sur les gâteaux, sur le thème anniversaire, sur le glaçage à la crème fouettée, puis vérifier tous les gâteaux qui sont intéressants en sachant qu'ils ont tous du glaçage à la crème fouettée. Ce n'est pas spécifique aux gâteaux, juste un exemple.

131
Zachary Scott

Il y a quelques avantages et inconvénients généraux auxquels je peux penser, il y a des situations où l'un est meilleur que l'autre:

Option 1, modèle EAV:

  • Pro: moins de temps pour concevoir et développer une application simple
  • Pro: nouvelles entités faciles à ajouter (pourraient même être ajoutées par les utilisateurs?)
  • Pro: composants d'interface "génériques"
  • Con: code complexe requis pour valider des types de données simples
  • Con: SQL beaucoup plus complexe pour les rapports simples
  • Inconvénients: les rapports complexes peuvent devenir presque impossibles
  • Inconvénients: performances médiocres pour les grands ensembles de données

Option 2, Modélisation de chaque entité séparément:

  • Con: plus de temps nécessaire pour recueillir les exigences et la conception
  • Inconvénients: les nouvelles entités doivent être modélisées et conçues par un professionnel
  • Con: composants d'interface personnalisés pour chaque entité
  • Pro: contraintes de type de données et validation simples à implémenter
  • Pro: SQL est facile à écrire, à comprendre et à déboguer
  • Pro: même les rapports les plus complexes sont relativement simples
  • Pro: meilleures performances pour les grands ensembles de données

Option 3, Combinaison (modélisez les entités "correctement", mais ajoutez des "extensions" pour les attributs personnalisés pour certaines/toutes les entités)

  • Pour/Con: plus de temps pour rassembler les exigences et la conception que l'option 1 mais peut-être pas autant que l'option 2 *
  • Inconvénients: les nouvelles entités doivent être modélisées et conçues par un professionnel
  • Pro: de nouveaux attributs pourraient être facilement ajoutés plus tard
  • Con: code complexe requis pour valider des types de données simples (pour les attributs personnalisés)
  • Con: composants d'interface personnalisés toujours requis, mais des composants d'interface génériques peuvent être possibles pour les attributs personnalisés
  • Con: SQL devient complexe dès qu'un attribut personnalisé est inclus dans un rapport
  • Inconvénients: bonnes performances en général, à moins que vous ne commenciez à chercher ou à signaler par les attributs personnalisés

* Je ne sais pas si l'option 3 gagnerait nécessairement du temps dans la phase de conception.

Personnellement, je pencherais pour l'option 2 et éviterais l'EAV autant que possible. Cependant, pour certains scénarios, les utilisateurs ont besoin de la flexibilité fournie avec EAV; mais cela vient avec un grand coût.

74
Jeffrey Kemp

Il est sûr de dire que le modèle de base de données EAV/CR est mauvais.

Non ce n'est pas. C'est juste qu'ils sont une utilisation inefficace des bases de données relationnelles. Un magasin purement clé/valeur fonctionne très bien avec ce modèle.

Maintenant, à votre vraie question: comment stocker divers attributs et les garder consultables?

Utilisez simplement EAV. Dans votre cas, ce serait une seule table supplémentaire. l'indexer à la fois sur le nom et la valeur de l'attribut, la plupart des RDBM utiliseraient la compression de préfixe sur les répétitions de noms d'attributs, ce qui le rend vraiment rapide et compact.

EAV/CR devient moche lorsque vous l'utilisez pour remplacer les "vrais" champs. Comme pour tout outil, sa surutilisation est "mauvaise" et lui donne une mauvaise image.

62
Javier

Je suis surpris que personne n'ait mentionné les bases de données NoSQL.

Je n'ai jamais pratiqué NoSQL dans un contexte de production (je viens de tester MongoDB et j'ai été impressionné) mais tout l'intérêt de NoSQL est de pouvoir enregistrer des éléments avec différents attributs dans le même "document".

15
Lucas T
 // À ce stade, je voudrais prendre un moment pour vous parler du Magento /Format Adobe PSD. 
 // Magento /PSD n'est pas une bonne plateforme de commerce électronique /format. Magento /PSD n'est même pas une mauvaise plateforme de commerce électronique /format. L'appeler ainsi serait une 
 // insulte à une autre mauvaise plateforme de commerce électronique /formats, comme Zencart ou OsCommerce. Non, Magento /PSD est une plate-forme de commerce électronique épouvantable /format. Ayant 
 // travaillé sur ce code depuis plusieurs semaines maintenant, ma haine pour Magento /PSD est devenu un feu qui fait rage 
 // qui brûle avec la passion féroce d'un million de soleils. 

http://code.google.com/p/xee/source/browse/trunk/XeePhotoshopLoader.m?spec=svn28&r=11#107

Les modèles internes sont au mieux farfelus, comme si quelqu'un mettait le schéma dans un jeu de boggle, scellait cela et le mettait dans un shaker de peinture ...

Monde réel: je travaille sur une application d'exécution de logiciels intermédiaires et voici l'une des requêtes pour obtenir des informations d'adresse.

CREATE OR REPLACE VIEW sales_flat_addresses AS
SELECT sales_order_entity.parent_id AS order_id, 
       sales_order_entity.entity_id, 
       CONCAT(CONCAT(UCASE(MID(sales_order_entity_varchar.value,1,1)),MID(sales_order_entity_varchar.value,2)), "Address") as type, 
       GROUP_CONCAT( 
         CONCAT( eav_attribute.attribute_code," ::::: ", sales_order_entity_varchar.value )
         ORDER BY sales_order_entity_varchar.value DESC
         SEPARATOR '!!!!!' 
       ) as data
  FROM sales_order_entity
       INNER JOIN sales_order_entity_varchar ON sales_order_entity_varchar.entity_id = sales_order_entity.entity_id
       INNER JOIN eav_attribute ON eav_attribute.attribute_id = sales_order_entity_varchar.attribute_id
   AND sales_order_entity.entity_type_id =12
 GROUP BY sales_order_entity.entity_id
 ORDER BY eav_attribute.attribute_code = 'address_type'

Exacte les informations d'adresse pour une commande, paresseusement

-

Résumé: N'utilisez Magento que si:

  1. On vous donne de gros sacs d'argent
  2. Vous devez
  3. Profitez de la douleur
15
Vee

Lorsque les performances ne sont pas une exigence majeure, comme dans une application de type ETL, l'EAV a un autre avantage distinct: les économies différentielles.

J'ai implémenté un certain nombre d'applications où une exigence générale était la possibilité de voir l'historique d'un objet de domaine depuis sa première "version" jusqu'à son état actuel. Si cet objet de domaine possède un grand nombre d'attributs, cela signifie que chaque modification nécessite l'insertion d'une nouvelle ligne dans sa table correspondante (pas une mise à jour car l'historique serait perdu, mais une insertion). Disons que cet objet de domaine est une personne, et j'ai 500 000 personnes à suivre avec une moyenne de plus de 100 changements au cours du cycle de vie des personnes pour divers attributs. Ajoutez à cela le fait que l'application est rare et ne comporte qu'un seul objet de domaine principal et vous supposerez rapidement que la taille de la base de données deviendrait rapidement incontrôlable.

Une solution simple consiste à enregistrer uniquement les modifications différentielles des principaux objets de domaine plutôt qu'à enregistrer à plusieurs reprises des informations redondantes.

Tous les modèles changent au fil du temps pour refléter les nouveaux besoins de l'entreprise. Période. L'utilisation de l'EAV n'est qu'un des outils de notre boîte à utiliser; mais il ne devrait jamais être automatiquement classé comme "mauvais".

11
Jerry Jasperson

Je me bats avec le même problème. Il peut être intéressant pour vous de consulter la discussion suivante sur deux solutions de commerce électronique existantes: Magento (EAV) et Joomla (structure relationnelle régulière): https://forum.virtuemart.net/index.php?topic= 58686.

Il semble que les performances EAV de Magento soient un véritable showstopper.

C'est pourquoi je penche vers une structure normalisée. Pour surmonter le manque de flexibilité, je pense ajouter à l'avenir un dictionnaire de données séparé (XML ou tables de base de données distinctes) qui pourraient être modifiées, et sur cette base, le code d'application pour afficher et comparer les catégories de produits avec de nouveaux attributs serait généré, ainsi que des scripts SQL.

Une telle architecture semble être le bonbon dans ce cas - flexible et performant à la fois.

Le problème pourrait être l'utilisation fréquente d'ALTER TABLE dans un environnement réel. J'utilise Postgres, donc son MVCC et son DDL transactionnel devraient, espérons-le, soulager la douleur.

3
aaimnr

Je vote toujours pour la modélisation au niveau atomique le moins significatif pour l'EAV. Laissez les normes, technologies et applications adaptées à certaines communautés d'utilisateurs décider des modèles de contenu, des besoins de répétition des attributs, des grains, etc.

2
Amanda Xu

S'il s'agit uniquement des attributs du catalogue de produits et que les exigences de validation pour ces attributs sont plutôt limitées, le seul véritable inconvénient de l'EAV est la performance des requêtes et même cela n'est un problème que lorsque votre requête concerne plusieurs "choses" (produits) avec des attributs, les performances de la requête "donnez-moi tous les attributs pour le produit avec l'ID 234" bien que non optimales sont encore très rapides.

Une solution consiste à utiliser le modèle de base de données SQL/EAV uniquement pour le côté admin/edit du catalogue de produits et d'avoir un processus qui dénormalise les produits en quelque chose qui le rend consultable. Puisque vous avez déjà des attributs et qu'il est donc probable que vous souhaitiez des facettes, ce quelque chose pourrait être Solr ou ElasticSearch. Cette approche évite essentiellement tous les inconvénients du modèle EAV et la complexité supplémentaire se limite à la sérialisation d'un produit complet vers JSON lors de la mise à jour.

2
bob

L'EAV présente de nombreux inconvénients:

  1. Dégradation des performances dans le temps Une fois que la quantité de données dans l'application dépasse une certaine taille, la récupération et la manipulation de ces données risquent de devenir de moins en moins efficaces.
  2. Les requêtes SQL sont très complexes et difficiles à écrire.
  3. Problèmes d'intégrité des données. Vous ne pouvez pas définir de clés étrangères pour tous les champs nécessaires.
  4. Vous devez définir et gérer vos propres métadonnées.
2
Gabriel Voinea

J'ai un problème légèrement différent: au lieu de nombreux attributs avec des valeurs rares (ce qui est peut-être une bonne raison d'utiliser EAV), je veux stocker quelque chose de plus comme une feuille de calcul. Les colonnes de la feuille peuvent changer, mais dans une feuille toutes les cellules contiendront des données (pas clairsemées).

J'ai fait un petit ensemble de tests pour comparer deux conceptions: l'une en utilisant EAV, et l'autre en utilisant un tableau Postgres pour stocker les données des cellules.

[~ # ~] eav [~ # ~] enter image description here

Tableau enter image description here

Les deux schémas ont des index sur les colonnes appropriées et les index sont utilisés par le planificateur.

Il s'est avéré le schéma basé sur un tableau était un ordre de grandeur plus rapide pour les insertions et les requêtes. D'après des tests rapides, il semble que les deux soient mis à l'échelle linéairement. Les tests ne sont cependant pas très approfondis. Les suggestions et les fourchettes sont les bienvenues - elles sont sous une licence MIT.

1
z0r