Ich überlege, ein Entity-Attribute-Value-Modell (EAV) für einige der in einem der Projekte enthaltenen Elemente zu verwenden, aber alle Fragen dazu in Stack Overflow führen dazu, dass die Antwort lautet, dass EAV ein Anti-Pattern ist.
Aber ich frage mich, ob es in allen Fällen so falsch ist.
Nehmen wir an, die Produktentität des Shops weist gemeinsame Merkmale wie Name, Beschreibung, Bild und Preis auf, die an vielen Orten logisch beteiligt sind, und (halb-) einzigartige Merkmale wie Uhr und Wasserball, die durch ganz unterschiedliche Aspekte beschrieben werden. Ich denke also, dass EAV für die Speicherung dieser (halb-) einzigartigen Funktionen geeignet wäre.
All dies setzt voraus, dass für die Anzeige der Produktliste genug Informationen in der Produkttabelle (dh es ist kein EAV beteiligt) vorhanden sind und nur für die Anzeige eines Produkts / für den Vergleich von bis zu 5 Produkten / usw. Daten, die mit EAV gespeichert wurden, werden verwendet.
Ich habe einen solchen Ansatz im Magento-Handel gesehen und er ist sehr beliebt. Gibt es also Fälle, in denen EAV sinnvoll ist?
Antworten:
https://web.archive.org/web/20140831134758/http://www.dbforums.com/database-concepts-design/1619660-otlt-eav-design-why-do-people-hate.html
EAV bietet dem Entwickler die Flexibilität, das Schema nach Bedarf zu definieren. Dies ist unter bestimmten Umständen hilfreich.
Auf der anderen Seite ist die Leistung bei einer schlecht definierten Abfrage sehr schlecht und kann andere schlechte Praktiken unterstützen.
Mit anderen Worten, EAV gibt Ihnen genug Seil, um sich zu erhängen, und in dieser Branche sollten die Dinge auf das niedrigste Maß an Komplexität ausgelegt werden, da der Typ, der Sie im Projekt ersetzt, wahrscheinlich ein Idiot sein wird.
quelle
Kurz gesagt, EAV ist nützlich, wenn Ihre Attributliste häufig wächst oder wenn sie so groß ist, dass die meisten Zeilen mit NULL-Werten gefüllt werden, wenn Sie jedes Attribut zu einer Spalte machen. Es wird zu einem Anti-Pattern, wenn es außerhalb dieses Kontexts verwendet wird.
quelle
CREATE TABLE
für das neue Attribut ausführen zu lassen ?Die Verwendung einer EAV-Struktur für hat mehrere Auswirkungen, die Kompromisse darstellen.
Sie tauschen weniger Platz für die Zeile aus, weil Sie nicht über 100 Spalten verfügen, die
null
für komplexere Abfragen und Modelle stehen.Ein EAV zu haben bedeutet normalerweise, dass der Wert eine Zeichenfolge ist, in die man beliebige Daten einfügen kann. Dies hat dann Auswirkungen auf die Gültigkeits- und Beschränkungsprüfung. Betrachten Sie die Situation, in der Sie die Anzahl der verwendeten Batterien in die EAV-Tabelle eingetragen haben. Sie möchten eine Taschenlampe finden, die Batterien der Größe C verwendet, aber weniger als 4 davon.
Hier ist zu beachten, dass Sie keinen vernünftigen Index für den Wert verwenden können. Sie können auch nicht verhindern, dass jemand etwas eingibt, das dort keine Ganzzahl ist, oder eine ungültige Ganzzahl (verwendet '-1' Batterien), da die Wertespalte immer wieder für andere Zwecke verwendet wird.
Dies hat dann Auswirkungen auf den Versuch, ein Modell für das Produkt zu schreiben. Hier finden Sie die schöne typisierten Werte haben ... aber du bist auch ein haben ,
Map<String,String>
gerade dort mit allen möglichen Sitz Sachen drin. Dies hat dann weitere Auswirkungen auf die Serialisierung in XML oder Json und die Komplexität des Versuchs, Validierungen oder Abfragen für diese Strukturen durchzuführen .Einige Alternativen oder Modifikationen des zu berücksichtigenden Musters bestehen darin, anstelle eines Freiformschlüssels eine andere Tabelle mit gültigen Schlüsseln zu haben. Dies bedeutet, dass Sie anstelle von Zeichenfolgenvergleichen in der Datenbank die Gleichheit von Fremdschlüssel-IDs überprüfen. Das Ändern des Schlüssels selbst erfolgt an einer Stelle. Sie haben einen bekannten Satz von Schlüsseln, was bedeutet, dass sie als Aufzählung durchgeführt werden können.
Sie können auch verknüpfte Tabellen haben, die Attribute einer bestimmten Produktklasse enthalten. Eine Lebensmittelabteilung könnte einen anderen Tisch haben, dem mehrere Attribute zugeordnet sind, die das Baumaterial nicht benötigt (und umgekehrt).
Es gibt Zeiten, in denen besonders eine EAV-Tabelle erforderlich ist.
Stellen Sie sich vor, Sie schreiben nicht nur ein Inventarsystem für Ihr Unternehmen, in dem Sie jedes Produkt und jedes Attribut kennen. Sie schreiben jetzt ein Inventarsystem, um es an andere Unternehmen zu verkaufen. Sie können nicht jedes Attribut jedes Produkts kennen - sie müssen sie definieren.
Eine Idee, die herauskommt, ist "wir lassen den Kunden die Tabelle modifizieren", und das ist nur schlecht (Sie kommen in die Metaprogrammierung für Tabellenstrukturen, weil Sie nicht mehr wissen, wo sich diese befinden, sie können die Struktur auf königliche Weise durcheinander bringen oder beschädigt werden In der Anwendung haben sie Zugriff darauf, um falsche Dinge zu tun, und die Auswirkungen dieses Zugriffs werden erheblich. In MVC4 gibt es mehr zu diesem Pfad : Wie erstelle ich ein Modell zur Laufzeit?
Stattdessen erstellen Sie die Verwaltungsschnittstelle zu einer EAV-Tabelle und lassen zu, dass diese verwendet wird. Wenn der Kunde einen Eintrag für 'Polkadots' erstellen möchte, wird dieser in die EAV-Tabelle eingetragen, und Sie wissen bereits, wie Sie damit umgehen müssen.
Ein Beispiel hierfür ist im Datenbankmodell für Redmine zu sehen. Sie können die Tabelle custom_fields und die Tabelle custom_values sehen. Dies sind Teile des EAV, mit denen das System erweitert werden kann.
Beachten Sie, dass Sie sich die KV-Variante von NoSQL (Cassandra, Redis, Mongo, ...) ansehen sollten, wenn Ihre gesamte Tabellenstruktur eher wie EAV als wie relational aussieht . Beachten Sie, dass diese häufig mit anderen Kompromissen in ihrem Design einhergehen, die möglicherweise nicht dem entsprechen, wofür Sie sie verwenden. Sie sind jedoch speziell mit der Absicht einer EAV-Struktur entworfen.
Möglicherweise möchten Sie SQL vs NoSQL für ein Bestandsverwaltungssystem lesen
Wenn Sie diesem Ansatz mit einer dokumentenorientierten NoSQL-Datenbank (couch, mongo) folgen, können Sie jedes Inventarelement als Dokument auf einer Festplatte betrachten. Das Aufrufen aller Elemente in einem einzelnen Dokument geht schnell. Darüber hinaus ist das Dokument so strukturiert, dass Sie jede einzelne Sache schnell herausziehen können. Auf der anderen Seite kann das Durchsuchen aller Dokumente nach Dingen, die einem bestimmten Attribut entsprechen, eine geringere Leistung haben (vergleiche 'grep' mit allen Dateien) ... es ist alles ein Kompromiss.
Ein anderer Ansatz wäre LDAP, bei dem eine Basis mit allen zugehörigen Elementen vorhanden ist, auf die dann jedoch auch zusätzliche Objektklassen für die anderen Elementtypen angewendet werden. (siehe Systeminventarisierung mit LDAP )
Wenn Sie diesen Weg einmal eingeschlagen haben, werden Sie vielleicht etwas finden, das genau zu dem passt, wonach Sie suchen ... obwohl alles mit gewissen Kompromissen verbunden ist.
quelle
6 Jahre später
Jetzt, da JSON in Postgres verfügbar ist, haben wir eine weitere Option für diejenigen, die Postgres verwenden. Wenn Sie nur einige zusätzliche Daten an ein Produkt anhängen möchten, sind Ihre Anforderungen recht einfach. Beispiel:
Hier ist eine leichtere Einführung in JSON in Postgres: https://www.compose.com/articles/is-postgresql-your-next-json-database/ .
Beachten Sie, dass Postgres tatsächlich JSONB und nicht JSON im Klartext speichert und Indizes für Felder in einem JSONB-Dokument / -Feld unterstützt, falls Sie feststellen, dass Sie tatsächlich eine Abfrage nach diesen Daten durchführen möchten.
Beachten Sie außerdem, dass Felder in einem JSONB-Feld nicht einzeln mit einer UPDATE-Abfrage geändert werden können. Sie müssten den gesamten Inhalt des JSONB-Felds ersetzen.
Diese Antwort behandelt die Frage möglicherweise nicht direkt, bietet jedoch eine Alternative zu einem EAV-Muster, das jeder berücksichtigen sollte, der über die ursprüngliche Frage nachdenkt.
quelle
jsonb_set()
In Postgres 9.5 und höher gibt es eine Funktion, die genau dafür vorgesehen ist. (Der Artikel, den Sie mit Links verknüpft haben, führt zu einem neueren Artikel, in dem die 9.5-Funktionen hinzugefügt wurden .)In der Regel schauen die Benutzer in die andere Richtung, wenn Sie es für Nachschlagetabellen verwenden, oder in anderen Situationen, in denen der Vorteil darin besteht, keine Tabellen für einen oder zwei gespeicherte Werte erstellen zu müssen. Die von Ihnen beschriebene Situation, in der Sie Elementeigenschaften speichern, klingt völlig normal (und normalisiert). Das Erweitern einer Tabelle zum Speichern einer variablen Anzahl von Elementattributen ist eine schlechte Idee.
Für den allgemeinen Fall, dass unterschiedliche Daten in einer langen, dünnen Tabelle gespeichert werden ... Sie sollten keine Angst haben , neue Tabellen zu erstellen, wenn dies erforderlich ist, und nur eine oder zwei lange, dünne Tabellen sind nicht viel besser als nur eine oder zwei zwei kurze fette Tische.
Abgesehen davon bin ich dafür berüchtigt, EAV-Tabellen für die Protokollierung zu verwenden. Sie haben einen guten Nutzen.
quelle
EAV wandelt das Problem der expliziten Struktur in implizite Wahrnehmung um. Anstatt zu sagen, dass X eine Tabelle mit den Spalten A und B ist, implizieren Sie, dass die Spalten A und B die Tabelle X bilden. In gewisser Hinsicht ist es umgekehrt, aber es gibt nicht unbedingt eine Eins-zu-Eins-Zuordnung. Man könnte sagen, dass A und B beide Tabellen (oder Typen) X und Y zugeordnet sind. Dies könnte in den Bereichen, in denen es auf den Kontext ankommt, wichtig sein.
Ich habe Datomic für diese Art von Ansatz studiert und ich denke, es ist ein sehr nützliches und leistungsfähiges System mit Einschränkungen, was Sie damit machen sollten (nicht, dass Sie es nicht könnten).
Dass EAV langsam ist oder "genug Seil gibt, um sich aufzuhängen", ist keine Aussage, der ich zustimmen würde. Eher würde ich die Stärken von EAV stärker betonen und wenn es Ihrem Problemraum entspricht, sollten Sie es in Betracht ziehen.
Ich habe die Erfahrung gemacht, dass dies ein wunderbarer, fast uneingeschränkter Ansatz für die Modellierung ist. Insbesondere im Fall von Datomic schreiben sie über allem eine festgelegte Semantik vor. Jede Modellierungsentscheidung, die eine Beziehung modelliert, kann frei von einer bis zu mehreren getroffen werden, ohne dass Spalten / Tabellen neu entworfen werden müssen. Sie können auch zurückgehen, solange die Einschränkung nicht gegen die Invariante verstößt. Unter der Haube ist es egal.
Das Problem mit EAV war in meinen Augen das Fehlen einer Implementierung wie Datomic. Da dies eine Frage zu EAV ist, möchte ich nicht über Datomic schwärmen, aber es ist eines dieser Dinge, bei denen ich denke, dass sie in Bezug auf EAV alles richtig gemacht haben.
quelle