Nous entendons beaucoup de gens sur internet se plaindre du modèle EAV de Magento. Avant de pouvoir Juger, il faut le comprendre. Je vais donc essayer de vous le montrer d’un point de vue « neutre ».
1) Définition : EAV C’est quoi ?
Entity–attribute–value model (EAV) is a data model to describe entities where the number of attributes (properties, parameters) that can be used to describe them is potentially vast, but the number that will actually apply to a given entity is relatively modest. In mathematics, this model is known as a sparse matrix. EAV is also known as object–attribute–value model, vertical database modeland open schema.
Extrait de wikipedia (5/2/2012) avant validation sur la non-prise de position
En compréhensible, car franchement la définition de Wikipedia n’est pas simple :-). Un modèle EAV est un modèle dans lequel nous déclarons des objets applicatifs sous forme de trois éléments : Une Entité (Un produit Magento par exemple), des attributs (La description par exemple), et des valeurs typées (le lipsum de la description) :-). A l’inverse un modèle type « Flat » lui déclarerait une table (entités) ou chaque attribut serait un champ et la valeur serait la donnée stockée.
Voilà une description neutre…
2) L’EAV dans Magento ?
Magento va encore plus loin que ce principe. En effet, deux séries de tables EAV s’appliquent pour un Objet par exemple de type Produit :
- Les tables EAV génériques, qui contiennent les attributs « commun » à tous les objets de type EAV.
- Les tables de spécialisations EAV qui permettent de surcharger les communes avec des informations propres à l’objet (ex type de produit)
3) EAV vs Flat ? Avantages ?
Pour ou Contre le modèle EAV ? Essayons d’être réaliste :
- Un modèle EAV permet à une application d’être flexible. En effet, le meilleur exemple est la création d’attributs à la volée sur un produit dans Magento. Effectivement, c’est vrai, mais un modèle classique pourrait gérer ce point avec une table d’attributs étendue, ou un simple alter table. Soyons réaliste, nous ne changeons pas les attributs des objets très souvent sur une application de production. Cet argument en fait un point technique qui n’est pas vraiment un avantage du modèle EAV.
- Le modèle EAV est peu performant. L’éclatement des données utiles en de multiples tables rend obligatoire de nombreuses jointures pour l’extraction d’un simple objet. C’est bien sur LE point faible du modèle EAV.
- La maintenabilité du système. Ceci est un point assez peu objectif, mais j’ai tendance à penser qu’un modèle plat classique même mal conçu (une petite exception pour le modèle d’un cms connu :-)), va forcément être plus abordable qu’un modèle EAV. Il est très (trop?) compliqué de corriger une erreur dans une table EAV type Magento ou les données peuvent se répartir dans 6 tables (voir plus) sur un même objet.
- Un typage très faible des données, et des contraintes de bases trop légères pour en assurer l’intégrité métier. Prenons un exemple simple, imaginons un article lié à un objet auteur dans une application que nous stockons dans une base EAV. Comment mettre une contrainte forte entre l’identifiant de l’auteur et l’article écrit… C’est un point important pour la cohérence d’un système.
J’ai beau chercher, je ne trouve pas d’avantage indiscutables, sauf peut-être la flexibilité du modèle EAV. Dans tous les cas, je ne trouve aucune raison justifiant les contraintes de maintenabilités. Je suis sur ce point très ouvert à vos retours…
4) Qu’est-ce que Magento gère en EAV ?
Pour connaitre la liste des objets stockés dans le modèle EAV de Magento, il faut exécuter la requête suivante :
SELECT * FROM `eav_entity_type`
Le résultat est actuellement sur une 1.6.x le suivant :
- customer
- customer_address
- catalog_category
- catalog_product
- order
- invoice
- creditmemo
- shipment
Globalement, les éléments critiques d’une boutique en ligne Magento (Orders, Products, Customers) sont dans les tables EAV.
5) Comment Magento contourne les problèmes de performances, et quand se produisent des problèmes de performances ?
La table EAV n’est pas en réalité si pénalisante pour tous. En fait, le moteur de magento est présent pour cacher d’un côté la complexité des requêtes aux développeurs, et de l’autre il réalise une interrogation relativement intelligente de ces tables pour être le moins pénalisant possible pour les performances.
Les tables EAV deviennent un problème important pour des bases de données contenant de nombreux produits, ou ayant de nombreuses vues produits. Si votre catalogue comporte 500 éléments, l’utilisation de ce modèle n’est pas vraiment grave. Lors de l’utilisation d’un large catalogue, vous comprendrez bien que ce schéma de base devient lourd.
Pour compenser, Magento met à votre disposition un modèle type « flat », les « flat » tables sont générées par Magento, il suffit de les autoriser via la configuration « Admin -> Configuration -> Catalogue -> Frontend » cochez « Utiliser un produit de catalogue fixe » et « Utiliser une catégorie de catalogue fixe ».
L’utilisation des tables « flat » vous permet alors de revenir sur un modèle classique souvent plus performant.
6) Un modèle d’ORM qui compense ?
Le modèle de Magento de gestion du mapping Objet / Stockage de données, permet de compenser pour les développeurs la complexité de l’EAV. Un effet pervers de la complexité du modèle EAV, est finalement qu’il va obliger les développeurs à ne surtout pas utiliser de requêtes SQL directe (ce que nous ne voyons que trop souvent!!!), au profit du Framework et des méthodes d’interrogations mises à disposition par Magento (ben voilà, un bon point ???J).
7) Conclusion, on reste neutre ou pas ?
Il est compliqué de rester neutre.
Magento ne prévoit pas de retirer le modèle EAV dans ses évolutions. Etant donné la qualité des gens travaillant sur Magento, il doit forcément y avoir de très bonnes raisons quant à l’utilisation d’une base EAV, que j’ignore complétement. Si vous en connaissez, je vous invite à me les faire parvenir via les commentaires.
La gestion de groupes d’attributs? (utilisé uniquement sur les produits)
Sinon je ne me suis pas trop penché sur la question, mais quels sont les risques de modification de structures intempestives (les attributs produits doivent pouvoir être manipulés facilement) sur une bdd massive en prod?
La modification de structure d’une base en production ne doit bien sur pas être réalisée en pleine charge. C’est une opération qui présente toujours un risque et j’imagine que le moindre Alter Table en production risque de demander un recalcul des index de la table (il est préférable de lancer ce type d’opération sur un replica de la base). Ce type de modification devraient être planifiées et mise en oeuvre en période creuse (si si, la nuit, il ne faut pas dormir :-)). Globalement que ce soit en EAV ou une modification de structure, les changements « intempestifs » sont très coûteux. Sur Magento, le prix à payer est souvent de re-créer les index, ce qui sur une base lourde est très long.
Bonjour,
Il y a quelques inexactitudes dans cet article.
Ce qui me saute aux yeux c’est l’eav au niveau des orders. Je suis désolé de l’annoncer mais ça a été retiré depuis la version 1.4.0.1. Depuis toutes les tables de type order/entity ont été remplacées par des tables de type flat/order (bien qu’il reste des résidus dans les tables eav_*)
Donc il reste de l’eav pour 4 éléments : customer, customer_address, catalog_category, catalog_product. Pour customer/customer_address, l’eav est discutable. Certes il ralenti la lecture (avec toute cette pléthore de ‘join’ niveau SQL), mais ça reste raisonnable, et permet de ce fait une modularité des attributs client. Sans grande importance donc.
En l’occurrence là où l’eav pèche bien évidement, c’est au niveau du catalogue. Bien que très modulaire, il ralenti considérablement le site (cf l’article) à partir d’un certain nombre de produits, surtout couplé avec différents stores. L’indexer est une solution, mais à mon avis pas viable puisqu’il implique des traitements doubles (eav et flat). Il n’y a donc pour le moment pas de solution et ils n’annoncent malheureusement pas de changements à ce niveau avec Magento 2 qui doit probablement être du à un retour arrière très complexe.
A voir donc 🙂
Bonjour,
Merci pour ce commentaire particulièrement complet.
Effectivement j’utilise une 1.4.x ce qui explique cette inexactitude.
Je vais modifier l’article très rapidement.
Merci
En dehors de l’EAV de magento (Que je connais que superficiellement), ce modèle de structuration de données (souvent utilisé par les développeurs sans savoir que c’est un standart – Vertical model – EAV – Etc…) est aussi très pratique et très souple pour gérer les valeurs multiples (Multivaluées), le multi-versionning de valeurs, le multilingues, etc…
Ces cas sont gérés, dans un modèle classique, avec des tables supplémentaires et qui finissent par alourdir également le code, les requêtes et la base de données. Le modèle EAV plus souple permet de les stocker dans les mêmes tables en les typant simplement sans grosses modifications du code et des requêtes…
Lavoisier disait : »Rien ne se perd, rien ne se crée, tout se transforme. » Je dirais en conclusion que pour répondre à une base de données simple, un modèle flat classique est bien plus performant, mais dans le cas contraire si on veut du multivalué, du multi-versionning, du multilingue, etc… les deux modèles aboutissent aux même résultats = Complexité et lourdeur.
Pour ma part, je préfère EAV pour sa souplesse anticipant la gestion des cas les plus complexes auxquelles on fini toujours par être confronté un jour ou l’autre dans tout projet informatique de long terme.
Mon expérience dans le logiciel est que si un client vous dit : »non je n’ai pas besoins du multilingues et je n’en aurais jamais besoins » => prévoyez le dans votre modèle de données ! car c’est la première évolution que votre client vous demandera… La loi de Murphy est une règle a prendre en compte dans notre métier !
Il faudrait donc apporter une réponse aux deux cas de figure selon les besoins des utilisateurs.
C’est en fait ce que nous avons fait en tant qu’étideur dans notre solution de Web Database qui a comme objectif de permettre de créer des applications de base de données simples ou complexes sans avoir a ce soucier du modèle de données. Bref un framework EAV et/ou CLASSIQUE.
Didier