web-dev-qa-db-fra.com

Alternatives à l'entité-attribut-valeur (EAV)?

Notre base de données est conçue sur la base du modèle EAV (entité-attribut-valeur). Ceux qui ont travaillé avec des modèles EAV connaissent toute la merde qui vient avec le but de la flexibilité.

J'ai demandé à mon client les raisons pour lesquelles utiliser le modèle EAV (flexibilité) et leur réponse était la suivante: leurs entités changent avec le temps. Ainsi, aujourd'hui, ils peuvent avoir une table avec quelques attributs, mais dans un mois, quelques nouveaux attributs peuvent être ajoutés, ou un attribut existant peut être renommé. Ils doivent produire des rapports pour revenir à n'importe quelle étape à temps et interroger les données basées sur la forme d'entités à ce stade.

Je comprends que cela n'est pas réalisable avec un modèle relationnel conventionnel, mais je vois personnellement EAV comme anti-motif. Y a-t-il d'autres modèles alternatifs qui nous permettent de capturer la dimension temporelle dans les modifications apportées aux entités et aux instances?

Acclamations, mosh

48
Mosh

Il y a une différence entre EAV fait fidèlement ou mal; 5nf fait par des personnes qualifiées ou par ceux qui sont désemparés.

Sixième forme normale est la forme normale irréductible (aucune autre normalisation n'est possible). Il élimine de nombreux problèmes communs, tels que le problème NULL, et fournit la méthode ultime identifiant les valeurs manquantes. C'est la NF académique et techniquement robuste. Il n'y a pas de produits pour le soutenir et il n'est pas couramment utilisé. Pour être mis en œuvre correctement et de manière cohérente, il faut mettre en œuvre un catalogue pour les métadonnées. Bien sûr, la SQL requise pour naviguer devient encore plus encombrante (SQL étant déjà encombrante Rejoints), mais cela est facilement surmonté en automatisant la production de SQL à partir des métadonnées.

EAV est un ensemble partiel ou un sous-ensemble de 6NF. Le problème est que cela est généralement fait dans un but (permettant d'ajouter des colonnes sans avoir à faire des changements DDL), et par des personnes qui ne sont pas au courant du 6NF et qui ne mettent pas en œuvre de métadonnées. Le but est, 6nf et EAV en tant que principes et concepts offrent des avantages substantiels et des augmentations de performance; Mais généralement, il n'est pas mis en œuvre correctement et les avantages ne sont pas réalisés. Toutes quelques mises en œuvre EAV sont des catastrophes, non pas parce que EAV est mauvais, mais parce que la mise en œuvre est médiocre.

Par exemple. Certaines personnes pensent que le SQL requis pour construire les lignes 3NF à partir de la base de données 6NF/EVV est complexe: Non, il est lourd mais pas complexe. Plus important encore, une vue SQL ordinaire peut être fournie, de sorte que tous les utilisateurs et tous les outils de rapport ne voient que la vue 3NF droite et les problèmes 6NF/EAV sont transparents pour eux. Enfin, le SQL requis peut être automatisé, de sorte que la main-d'œuvre coûte que de nombreuses personnes subissent assez inutiles.

La réponse est donc réellement, la sixième forme normale, étant le père de EAV et une forme plus pure, est le remplacement de celui-ci. La mise en garde est, assurez-vous qu'il est fait correctement. J'ai une grande dB 6NF, et elle ne subit aucun problème de publication de personnes, il fonctionne magnifiquement, le client est très heureux (aucun autre travail n'est un signe de satisfaction fonctionnelle complète).

J'ai déjà posté une réponse très détaillée à une autre question qui s'applique également à votre question, que vous pouvez être intéressé.

Autre question EAV

51
PerformanceDBA

Quel que soit le type de modèle relationnel que vous utilisez, les modifications de nom de champ de suivi nécessitent beaucoup de métadonnées que vous devez suivre les journaux de transaction ou les tables d'audit. Malheureusement, interroger l'un ou l'autre de ceux de l'état à une date particulière est très compliqué. Si votre client ne nécessite que l'état à une date de temps en particulier, ce qui signifie que l'état entier, non seulement en ce qui concerne les modifications de nom, vous pouvez dupliquer la base de données et publier le journal de transaction au moment requis et exécutez vos requêtes sur la nouvelle instance. . Si des entités ajoutées après la date spécifiée doivent apparaître dans la requête avec les anciens noms de champs, vous avez un très grand problème d'ingénierie devant vous. Dans ce cas, avec les informations que vous avez fournies dans votre question, je suggérerais de négocier des alternatives avec le client ou d'obtenir plus d'informations sur l'utilisation des rapports pour trouver de nombreuses solutions.

Vous pouvez vous déplacer dans un magasin de données basé sur le document, mais cela ne résoudrait toujours pas le problème dans le second cas. Désolé, ce n'est pas vraiment une réponse, mais avoir travaillé dans des situations similaires, le client a probablement besoin d'une solution de reporting plus réaliste ou d'un certain nombre d'autres investisseurs disposés à la capitale de l'ingénierie.

Lorsque ce problème est arrivé pour nous, nous avons conservé la constante de schéma de la DB et mis en œuvre une usine de mappage d'entité basée sur un horodatage. En fin de compte, le client a constamment modifié les exigences (chaque semaine à la base mensuelle) quant à la manière dont les champs d'agrégats ont été calculés et n'ont jamais été pleinement satisfaits.

9
Nick Larsen

Pour ajouter aux réponses de @nicklarsen et @performancedba

Si vous avez besoin de suivre les modifications historiques des choses telles que le nom de champ, vous voudrez peut-être examiner quelque chose comme modifier lentement des dimensions . Il me semble que vous utilisez l'EAV pour modéliser des modèles dimensionnels dynamiques (probablement des listes de recherche).

La manière la plus simple (et probablement moins efficace) de réaliser cela serait d'inclure un champ de date "à partir de" sur les tables EAV, et chaque fois qu'un changement se produit, insérez un nouvel enregistrement (au lieu de mettre à jour un enregistrement existant) avec la date actuelle. Cela signifie que vous devez modifier vos requêtes pour toujours inclure ou rechercher une date "à partir de", ou sourdulte à "maintenant" si jamais. Votre entité de base qui se joint aux objets EAV devrait alors interroger "le top 1" de la table EAV où la date "à partir de" est inférieure ou égale à la date "Dernière mise à jour" de la ligne, commandée par "à partir de" descendant. Scénario des pires cas, si vous devez suivre le changement le plus récent à une ligne donnée où le nom (stocké dans la table "Attribut") et la valeur a changé, vous alliez chaînerez cette logique à la table de valeurs à l'aide de "Dernière modification". de la ligne pour trouver la valeur appropriée pour cette date particulière.

Cela a évidemment le potentiel de générer de grandes quantités de données s'il ya beaucoup de changements. C'est pourquoi cette approche est appelée "lentement" changeant. Il est destiné aux valeurs dimensionnelles qui peuvent changer, mais pas très souvent. Pour vous aider avec la performance de la requête, les index sur les champs "à partir" et "Dernier modifié" devraient aider.

0
CodeMonkey