Supposons qu'une entité de produit de magasin ait des caractéristiques communes, telles que le nom, la description, l'image, le prix, etc., qui participent à la logique de nombreux lieux et présente des caractéristiques (semi) uniques, telles que la montre et le ballon de plage. . Donc, je pense qu'EAV conviendrait pour stocker ces caractéristiques (semi) uniques?
L'utilisation d'une structure EAV a plusieurs implications qui sont des compromis.
Vous négociez "moins d'espace pour la ligne, car vous ne disposez pas de 100 colonnes null
" contre "des requêtes et un modèle plus complexes".
Avoir un EAV signifie généralement que la valeur est une chaîne dans laquelle on peut rentrer toutes les données. Ceci a alors des implications sur la vérification de la validité et des contraintes. Considérez le cas où vous avez mis le nombre de piles utilisées dans le tableau EAV. Vous voulez trouver une lampe de poche utilisant des piles de taille C, mais moins de 4 d'entre elles.
select P.sku
from
products P
attrib Ab on (P.sku = Ab.sku and Ab.key = "batteries")
attrib Ac on (P.sku = Ac.sku and Ac.key = "count")
where
cast(Ac.value as int) < 4
and Ab.value = 'C'
...
La chose à réaliser ici est que vous ne pouvez pas utiliser un index de manière raisonnable sur la valeur. Vous ne pouvez pas non plus empêcher quelqu'un d'introduire quelque chose qui n'est pas un entier ou un entier non valide (utilise des piles '-1') car la colonne de valeurs est utilisée encore et encore à des fins différentes.
Cela a alors des implications pour essayer d’écrire un modèle pour le produit. Vous aurez les bonnes valeurs dactylographiées ... mais vous allez également avoir une Map<String,String>
assise juste avec toutes sortes de choses dedans. Cela a alors des implications supplémentaires lors de la sérialisation en XML ou Json et de la complexité d'essayer de valider ou d'interroger ces structures.
Certaines alternatives ou modifications du modèle à prendre en compte consistent, au lieu d'une clé de forme libre, à avoir une autre table avec des clés valides. Cela signifie qu'au lieu de faire des comparaisons de chaînes dans la base de données, vous vérifiez par rapport à l'égalité des identifiants de clé étrangère. Changer la clé elle-même se fait en un seul endroit. Vous avez un jeu de clés connu, ce qui signifie qu'elles peuvent être effectuées en tant qu'énum.
Vous pouvez également disposer de tables associées contenant les attributs d'une classe de produit spécifique. Un département d'épicerie peut avoir une autre table qui a plusieurs attributs associés dont les matériaux de construction n'ont pas besoin (et vice versa).
+----------+ +--------+ +---------+
|Grocery | |Product | |BuildMat |
|id (fk) +--->|id (pk) |<---+id (fk) |
|expiration| |desc | |material |
|... | |img | |... |
+----------+ |price | +---------+
|... |
+--------+
Il y a des moments qui appellent particulièrement une table EAV.
Pensez à la situation dans laquelle vous n'êtes pas simplement en train d'écrire un système d'inventaire pour votre entreprise dans lequel vous connaissez chaque produit et chaque attribut. Vous écrivez maintenant un système d'inventaire à vendre à d'autres entreprises. Vous ne pouvez pas connaître tous les attributs de chaque produit - ils devront les définir.
Une idée qui en ressort est "nous laisserons le client modifier la table" et c'est tout simplement mauvais (vous entrez dans la méta-programmation pour les structures de table parce que vous ne savez plus où se trouve, elles peuvent corrompre royalement ou corrompre l'application, ils ont le droit de faire de mauvaises choses et les implications de cet accès deviennent importantes). Il existe plus d'informations sur ce chemin sur MVC4: Comment créer un modèle au moment de l'exécution?
Au lieu de cela, vous créez l'interface administrative dans une table EAV et autorisez son utilisation. Si le client veut créer une entrée pour 'polkadots', il va dans la table EAV et vous savez déjà comment gérer cela.
Un exemple de ceci peut être vu dans le modèle de base de données pour Redmine, vous pouvez voir la table custom_fields, et la table custom_values - ce sont des parties de l'EAV qui permet d'étendre le système.
Notez que si vous trouvez que votre structure de table entière ressemble à EAV plutôt que relationnelle, vous voudrez peut-être examiner la version KV de NoSQL (cassandra, redis, mongo, ...). Sachez que ceux-ci viennent souvent avec d’ autres compromis dans leur conception qui peuvent ou non être appropriés à l’utilisation que vous en faites. Cependant, ils sont spécifiquement conçus avec l'intention d'une structure EAV.
Vous voudrez peut-être lire SQL vs NoSQL pour un système de gestion d'inventaire
En suivant cette approche avec une base de données NoSQL orientée document (divan, mongo), vous pouvez considérer chaque article d'inventaire comme un document sur un disque ... tout en un dans un document est rapide. En outre, le document est structuré de sorte que vous puissiez extraire rapidement une seule chose. D'autre part, rechercher dans tous les documents des éléments correspondant à un attribut particulier peut avoir des performances moindres (comparer avec "grep" contre tous les fichiers) ... c'est tout un compromis.
Une autre approche serait LDAP, dans laquelle on disposerait d'une base avec tous les éléments associés, mais on appliquerait également des classes d'objet supplémentaires pour les autres types d'éléments. (voir Inventaire du système avec LDAP )
Une fois que vous empruntez ce chemin, vous pouvez trouver quelque chose qui correspond exactement à ce que vous recherchez ... même si tout est assorti de compromis.