Meilleur modèle pour stocker les attributs (produit) dans SQL Server
Nous sommes au début d'un nouveau projet lorsque nous avons besoin de stocker des produits et de nombreux attributs du produit dans une base de données. La technologie de la pile est MS SQL 2008 et Entity Framework 4.0 /LINQ pour l'accès aux données.
Les produits (et les Produits de la Table) sont assez simple (un SKU, fabricant, prix, etc..). Il existe toutefois de nombreux attributs de magasin avec chaque produit (pensez industrielle widgets). Il peut s'agir de la couleur à la certification(s) à la taille du tuyau. Chaque produit peut avoir des attributs différents, et certains ont peut-être des multiples de la même attribut (Ex: Certifications).
La proposition actuelle est que l'on aura fondamentalement une paire nom/valeur de la table avec un FK retour à 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 serait probablement venir d'une table de recherche ou enum.
De sorte que la principale question qui se pose ici est: Est-ce le meilleur modèle pour faire quelque chose comme ça? Comment la performance? Les questions seront basées sur une JOINTURE du produit et les attributs de la table, et généralement besoin de beaucoup de WHEREs de filtre sur des attributs les plus courants de recherche sera de trouver un produit basé sur un ensemble de connu/caractéristiques désirées.
Si quelqu'un a des suggestions ou un meilleur modèle pour ce type de données, s'il vous plaît laissez-moi savoir.
Merci!
-Ed
source d'informationauteur EdH
Vous devez vous connecter pour publier un commentaire.
Vous êtes sur le point de ré-inventer la redoutable EAV modèle Entité-Attribut-Valeur. C'est connue pour avoir des problèmes dans la vie réelle, pour diverses raisons, de nombreux couverts par Dave réponse.
Heureusement SQL Client Consultatif de l'Équipe (sqlcat (en anglais)) a un livre blanc sur le sujet,
Les meilleures Pratiques Sémantique pour la Modélisation des Données de Performance et d'Évolutivité. Je recommande fortement ce livre. Malheureusement, il n'offre pas une panacée, un emporte-pièce de solution, car le problème n'a pas de solution. Au lieu de cela, vous allez apprendre à trouver l'équilibre entre un fixe queryable schéma et un flexible de VAE de la structure, un équilibre qui fonctionne pour votre cas spécifique:
Cela va être problématique pour deux raisons:
Votre entité requêtes sera beaucoup plus difficile à écrire. Transformer les résultats de ces requêtes en quelque chose ressemblant à un ViewModel quand vient le temps pour la présentation va être douloureux, car il implique un pivot pour chaque produit.
La compréhension de ce que vos types de données va être va être difficile quand vient le temps de lire certains types de données. Envisagez-vous sur l'entreposage de ces chaînes? Par exemple, DateTimes contenir plus de données que la valeur par défaut .ToString() de la mise en œuvre, écrit à la chaîne. Vous allez également avoir des problèmes si vous essayez de stocker des valeurs en virgule flottante.
De vos objets à l'intégrité des données est à risque. Il y aura une tentation de mettre les propriétés qui doivent être les attributs de votre produit principal de tables dans ce seau "o " données". Peut-être que la conception sera semi-sane, pour commencer, mais je vous garantie qu'après un certain laps de temps, les gens vont commencer à simplement jeter propriétés dans le sac. Il sera ensuite très difficile de garder vos objets de l'intégrité avec une telle vaguement défini la structure.
Votre index est le plus susceptible d'être sous-optimale. De nouveau penser à une propriété qui doit être sur votre table de produit. Au lieu d'être en mesure de l'index sur une colonne, vous allez maintenant être obligé de faire un très grand indice composite sur votre "type" de la table.
Puisque vous êtes apparemment l'intention de lancer proprement types de données et l'utilisation des cordes, les performances des requêtes de plage pour les données numériques seront probablement mauvaise.
Votre table aura de grandes, le ralentissement des sauvegardes et des requêtes. Au lieu d'un entier soit 4 octets, vous allez avoir à stocker beaucoup plus pour un entier de toute taille.
Mieux à normaliser la table dans une plus de manière "traditionnelle" à l'aide "EST-UN" relations". Par exemple, vous pourriez avoir des Tuyaux, qui sont un type de Produit, mais ils ont un couple de plusieurs attributs. Vous pourriez avoir des Poêles, qui sont un type de produit, mais ils ont un couple de plusieurs attributs encore.
Si vraiment vous avez une base de données générique et toutes sortes d'autres propriétés qui ne vont pas être soumis à des règles d'intégrité de données, vous peut très bien envisager de stocker des données dans une colonne XML. Il est difficile de vous dire ce que le bon choix de conception est, à moins que j'en sais beaucoup plus sur votre entreprise.
IMO c'est une conception antipattern. Le chant de sirène de cette idée, qui a attiré beaucoup de développeur sur les rochers de de un désuète application.
Je sais il est vieux - cependant il y a peut être d'autres lecteurs...
J'ai vu le solde de la VAE pour l'attribut modélisé approche. Bien qu'il est encore EAV. "EAV sont comme des drogues" est à peu près vrai. Alors quoi penser de travers une fois de plus - et nous allons être vraiment agressif:
J'ai toujours aimé le supertype apporach, où un grand nombre de tables à utiliser la même clé primaire à partir d'un générateur de clés. Nous allons utiliser ce un. Alors que pensez-vous de la création d'une nouvelle table pour chaque ensemble d'attributs, tout en ayant la primaire dans le même générateur de clé? Par exemple. vous avez une table avec les champs "de la couleur,de la pipe", un autre tableau "fittingsize,pipe", et ainsi de suite. L'exigence de la "volatilité des attributs" hurle pour un soin(automatiquement) a maintenu dictionnaire de données, de toute façon.
Cette approche est entièrement normalisée et peut être entièrement automatisé. Vous pouvez soutenir vérifie si les ensembles d'attributs matérialisé déjà de la table de hachage nom de l'attribut de clusters, par exemple. crc32(lower('color~fittingsize~pipe')) où l'attribut noms doivent être triés par ordre alphabétique. Bien sûr, cela nécessite d'avoir le hachage dans le dictionnaire de données. Sur la base des données de dictionnaire chaque objet peut être recherché (à l'aide de "UNION"), surtout si le dictionnaire de données elle-même est une table. Avoir le dictionnaire des données de la table vous permet également d'utiliser ses primaire (de substitution) comme base pour unique tablenames, pour finir avec des tableaux comme "attributes1','attributes2',... la Plupart des bases de données aujourd'hui le soutien de quelques milliards de tables - nous sommes donc en sorte de sauver sur cette fin ainsi. Vous pourriez même avoir un produit catalouge avec de très attributs communs, qui fait référence à l'attribut étendu tables.
Une question ouverte est de 1 à n ensembles de données. Je crains que vous avez besoin de les trier dans des tables distinctes. Toutefois, cela dépend beaucoup de votre présentation des données et l'interrogation de la stratégie. Devraient-ils toujours être présentées de la séparation par virgule corde attachée au produit ou voulez-vous par exemple. être capable de faire une requête pour tous les produits d'une Certification?
Avant de vous la flamme de cette approche veuillez en tenir compte: Il est conçu pour l'utilisation le cas où vous avez une très forte volatilité sur les attributs, en quantité et en qualité. Il a également été prédéfinis, que vous ne pouvez pas connaître la plupart des attributs à un point dans le temps lorsque la solution est créé. Donc, ne pas discuter de cela dans un contexte où vous pouvez modéliser votre attributs initiaux qui vous permettrait de l'équilibre des échanges beaucoup mieux.
En bref, vous ne pouvez pas aller tous un itinéraire. Si vous utilisez une VAE comme votre exemple, vous aurez une multitude de problèmes tels que ceux décrits par les autres affiches pas le moindre de ce qui sera la performance et l'intégrité des données. Permettez-moi de rappeler que l'utilisation d'un VAE au cœur de votre solution échouera quand vous arrivez à la présentation et à l'analyse. Cependant, comme vous l'avez dit aussi, vous pourriez avoir des centaines d'attributs qui changent régulièrement.
La solution, OMI, est un hybride. Pour les attributs communs, à l'aide des colonnes/schéma standard. Pour plus d', arbitraire attributs, l'utilisation d'un VAE. Cependant, la règle de l'EAV des données est que vous ne pouvez jamais, jamais, sous aucun prétexte, d'écrire une requête qui inclut un tri ou de filtre sur un attribut. I. e., vous pouvez ne jamais écrire
Where AttributeName = 'Foo'
. L'EAV partie du schéma représente un sac de données qui est seulement là pour des fins de suivi. En fait, j'ai vu beaucoup de gens de mettre en œuvre cette solution par l'utilisation de Xml pour la VAE partie. Le moment où quelqu'un ne veut de recherche, de filtrage, de tri ou de passer une VAE valeur dans un endroit précis sur un rapport, cet attribut doit être élevée à un niveau supérieur de la colonne dans la table produits.La clé de cette approche hybride est la discipline. Il semble assez simple pour ajouter un filtre, de tri ou de mettre un attribut dans un endroit précis, quelque part sur un rapport en particulier lorsque la pression de la direction. Vous devez résister à cette tentation. Une fois que vous descendez le chemin sombre... Si vous ne pensez pas que vous pouvez maintenir ce niveau de la discipline dans le développement de votre équipe, alors je ne voudrais pas utiliser un VAE. Comme je l'ai mentionné avant, EAV sont comme les médicaments: en petites quantités et utilisé dans les bonnes circonstances, ils peuvent être bénéfiques. Trop de va vous tuer.
Plutôt que d'avoir un nom et d'une table de valeurs, de créer le Produit d'habitude structure de la table contenant l'ensemble des attributs communs, et d'ajouter une colonne XML pour les attributs qui varient selon le produit.
J'ai utilisé cette structure avant et ça marchait assez bien.
@Dave Markle mentionne le nom de l'approche de la valeur peut conduire à un monde de douleur.