Meilleur modèle pour stocker les attributs (produit) dans SQL Server

database database-design entity-framework sql sql-server

Question

Nous commençons un nouveau projet dans lequel nous devons stocker le produit et de nombreux attributs dans une base de données. La pile technologique est MS SQL 2008 et Entity Framework 4.0 / LINQ pour l’accès aux données.

Les produits (et la table des produits) sont assez simples (SKU, fabricant, prix, etc.). Cependant, il existe également de nombreux attributs à stocker avec chaque produit (pensez aux widgets industriels). Celles-ci peuvent aller de la couleur à la certification, en passant par la taille du tuyau. Chaque produit peut avoir des attributs différents, et certains peuvent avoir des multiples du même attribut (Ex: Certifications).

Selon la proposition actuelle, nous aurons essentiellement une table de paires nom / valeur avec un FK correspondant à l'ID de produit dans chaque ligne.

Un exemple de la table d'attributs peut ressembler à ceci:

ProdID     AttributeName     AttributeValue
123        Color             Blue
123        FittingSize       1.25
123        Certification     AS1111
123        Certification     EE2212
123        Certification     FM.3
456        Pipe              11
678        Color             Red
999        Certification     AE1111
...

Remarque: Le nom de l'attribut proviendrait probablement d'une table de consultation ou d'une énumération.

La question principale est donc la suivante: est-ce le meilleur modèle pour faire quelque chose comme ça? Comment sera la performance? Les requêtes seront basées sur une jointure du produit et de la table d'attributs et nécessitent généralement de nombreux filtres WHERE pour filtrer des attributs spécifiques. La recherche la plus courante consiste à rechercher un produit basé sur un ensemble d'attributs connus / souhaités.

Si quelqu'un a des suggestions ou un meilleur modèle pour ce type de données, veuillez me le faire savoir.

Merci! -Ed

Réponse acceptée

Vous êtes sur le point de réinventer le modèle EAV redouté, Entity-Attribute-Value. Ceci est notoire pour avoir des problèmes dans la vie réelle, pour diverses raisons, dont beaucoup sont couvertes par la réponse de Dave.

Heureusement, l'équipe de conseil aux clients SQL (SQLCAT) a publié un livre blanc sur le sujet, " Meilleures pratiques pour la modélisation de données sémantiques pour des performances et une évolutivité optimales" . Je recommande fortement ce papier. Malheureusement, cela ne constitue pas une panacée, une solution à l'emporte-pièce, car le problème n'a pas de solution. Au lieu de cela, vous apprendrez à trouver un équilibre entre un schéma pouvant être interrogé fixe et une structure EAV flexible, un équilibre qui convient à votre cas spécifique:

Les modèles de données sémantiques peuvent être très complexes et jusqu'à ce que des bases de données sémantiques soient disponibles, le défi reste de trouver l'équilibre optimal entre le modèle objet pur et le modèle relationnel pur pour chaque application. La clé du succès consiste à comprendre les problèmes, à prendre les mesures nécessaires pour les résoudre, puis à tester, tester et tester. Le test d’évolutivité est un facteur de succès essentiel si vous voulez trouver cette conception optimale.


Réponse populaire

Cela va poser problème pour plusieurs raisons:

  • Vos requêtes d'entité seront beaucoup plus difficiles à écrire. Transformer les résultats de ces requêtes en quelque chose qui ressemble à un ViewModel au moment de la présentation va être pénible, car cela impliquera un pivot pour chaque produit.

  • Comprendre ce que seront vos types de données sera difficile au moment de lire certains types de données. Envisagez-vous de stocker ceci en tant que chaînes? Par exemple, DateTimes contient plus de données que l'implémentation par défaut .ToString () écrit dans la chaîne. Vous aurez également des problèmes si vous essayez de stocker des valeurs à virgule flottante.

  • L'intégrité des données de vos objets est menacée. Il y aura une tentation de mettre des propriétés qui ne devraient être que des attributs de vos principales tables de produits dans ce "compartiment de données". La conception sera peut-être à moitié saine d'esprit au début, mais je vous garantis qu'après un certain laps de temps, les gens commenceront simplement à jeter des propriétés dans le sac. Il sera alors très difficile de conserver l'intégrité de vos objets avec une structure aussi vague.

  • Vos index seront probablement sous-optimaux. Encore une fois, pensez à une propriété qui devrait figurer sur votre table de produits. Au lieu de pouvoir indexer sur une seule colonne, vous allez maintenant être obligé de créer un index composite potentiellement très volumineux sur votre table "type".

  • Puisque vous envisagez apparemment de supprimer les types de données appropriés et d'utiliser des chaînes, les performances des requêtes de plage pour les données numériques seront probablement médiocres.

  • Votre table deviendra grande, ralentissant les sauvegardes et les requêtes. Au lieu d'un entier de 4 octets, vous devrez en stocker beaucoup plus pour un entier de toute taille.

Mieux vaut normaliser la table de manière plus "traditionnelle" en utilisant les relations "IS-A". Par exemple, vous pouvez avoir des pipes, qui sont un type de produit, mais qui ont quelques attributs en plus. Vous pouvez avoir des poêles, qui sont un type de produit, mais qui ont encore quelques attributs.

Si vous avez réellement une base de données générique et toutes sortes d'autres propriétés qui ne seront pas soumises aux règles d'intégrité des données, vous voudrez peut-être envisager de stocker des données dans une colonne XML. Il est difficile de vous dire quel est le bon choix de design, à moins que j'en sache beaucoup plus sur votre entreprise.

OMI c'est un anti-modèle de conception. Le chant de sirène de cette idée a attiré beaucoup de développeurs sur les fondements d’une application impossible à maintenir.



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow