Man kann mit Sicherheit sagen, dass das Datenbankmodell EAV/CR schlecht ist. Das gesagt,
Frage: Welches Datenbankmodell, -technik oder -muster sollte verwendet werden, um mit "Klassen" von Attributen umzugehen, die E-Commerce-Produkte beschreiben, die zur Laufzeit geändert werden können?
In einer guten E-Commerce-Datenbank werden Sie Optionsklassen speichern (z. B. TV-Auflösung hat dann eine Auflösung für jedes Fernsehgerät, aber das nächste Produkt ist möglicherweise kein Fernsehgerät und hat keine "TV-Auflösung"). Wie können Sie sie speichern, effizient suchen und Ihren Benutzern ermöglichen, Produkttypen mit variablen Feldern einzurichten, die ihre Produkte beschreiben? Wenn die Suchmaschine feststellt, dass Kunden in der Regel anhand der Konsolentiefe nach Fernsehgeräten suchen, können Sie Ihren Feldern eine Konsolentiefe hinzufügen und dann zur Laufzeit für jeden TV-Produkttyp eine einzelne Tiefe hinzufügen.
Gute E-Commerce-Apps haben eine gemeinsame Funktion: Sie zeigen eine Reihe von Produkten an und haben dann Seitenmenüs, in denen "TV Resolution" als Überschrift angezeigt wird, sowie die fünf häufigsten TV-Auflösungen für das gefundene Menge. Wenn Sie auf eines klicken, werden nur Fernsehgeräte mit dieser Auflösung angezeigt, sodass Sie weitere Details anzeigen können, indem Sie andere Kategorien im Seitenmenü auswählen. Diese Optionen sind die dynamischen Produktattribute, die zur Laufzeit hinzugefügt werden.
Weitere Diskussion:
Also, um es kurz zu machen, gibt es Links im Internet oder Modellbeschreibungen, die das folgende Setup "akademisch" korrigieren könnten? Ich danke Noel Kennedy für den Vorschlag eine Kategorietabelle, aber der Bedarf kann größer sein. Ich beschreibe es weiter unten anders und versuche, die Bedeutung herauszustellen. Möglicherweise benötige ich eine Blickwinkelkorrektur, um das Problem zu lösen, oder ich muss mich eingehender mit dem EAV/CR befassen.
Ich liebe die positive Resonanz auf das EAV/CR-Modell. Meine Kollegen sagen alle, was Jeffrey Kemp unten angesprochen hat: "Neue Entitäten müssen von einem Fachmann modelliert und entworfen werden" (aus dem Zusammenhang herausgenommen, lesen Sie seine Antwort unten). Das Problem ist:
Der Kunde möchte den Produkten aus zwei Gründen Attribute hinzufügen:
Die Attribute müssen eine Bedeutung haben, nicht nur eine Stichwortsuche. Wenn sie alle Kuchen vergleichen möchten, die einen "Schlagsahne-Zuckerguss" haben, können sie auf Kuchen klicken, auf Geburtstagsthema klicken, auf Schlagsahne-Zuckerguss klicken und dann alle Kuchen überprüfen, die interessant sind und wissen, dass sie alle Schlagsahne-Zuckerguss haben. Dies ist nicht spezifisch für Kuchen, nur ein Beispiel.
Ich kann mir ein paar allgemeine Vor- und Nachteile vorstellen. Es gibt Situationen, in denen eines besser ist als das andere:
Option 1, EAV-Modell:
Option 2, jede Entität separat modellieren:
Option 3, Kombination (modelliere Entitäten "richtig", füge aber "Erweiterungen" für benutzerdefinierte Attribute für einige/alle Entitäten hinz
* Ich bin nicht sicher, ob Option 3 in der Entwurfsphase unbedingt Zeit sparen würde.
Persönlich würde ich mich zu Option 2 neigen und EAV nach Möglichkeit vermeiden. Für einige Szenarien benötigen die Benutzer jedoch die mit EAV verbundene Flexibilität. Dies ist jedoch mit hohen Kosten verbunden.
Man kann mit Sicherheit sagen, dass das EAV/CR-Datenbankmodell schlecht ist.
Nein, ist es nicht. Es ist nur so, dass sie eine ineffiziente Nutzung relationaler Datenbanken sind. Ein reiner Schlüssel-/Wertspeicher eignet sich hervorragend für dieses Modell.
Nun zu Ihrer eigentlichen Frage: Wie können verschiedene Attribute gespeichert und durchsuchbar gehalten werden?
Verwenden Sie einfach EAV. In Ihrem Fall wäre es eine einzelne zusätzliche Tabelle. Indizieren Sie es sowohl für den Attributnamen als auch für den Wert. Die meisten RDBMs verwenden die Präfixkomprimierung für die Wiederholungen von Attributnamen, wodurch es sehr schnell und kompakt wird.
EAV/CR wird hässlich, wenn Sie es verwenden, um "echte" Felder zu ersetzen. Wie bei jedem Werkzeug ist eine Überbeanspruchung „schlecht“ und ergibt ein schlechtes Image.
Ich bin überrascht, dass niemand NoSQL-Datenbanken erwähnt hat.
Ich habe NoSQL noch nie in einem Produktionskontext geübt (habe gerade MongoDB getestet und war beeindruckt), aber der springende Punkt bei NoSQL ist, Elemente mit unterschiedlichen Attributen in demselben "Dokument" zu speichern.
// An dieser Stelle möchte ich mir einen Moment Zeit nehmen, um mit Ihnen über das Magento zu sprechen /Adobe PSD-Format. // Magento /PSDist keine gute E-Commerce-Plattform /format. Magento /PSDist nicht einmal eine schlechte E-Commerce-Plattform /format. Das so zu nennen, wäre eine // Beleidigung für eine andere schlechte E-Commerce-Plattform /formate, wie Zencart oder OsCommerce. Nein, Magento /PSDist eine abgründige E-Commerce-Plattform /format. Nachdem ich // seit einigen Wochen an diesem Code arbeite, hasse ich Magento /PSDist zu einem tobenden Feuer gewachsen, das mit der Leidenschaft von einer Million Sonnen brennt.
http://code.google.com/p/xee/source/browse/trunk/XeePhotoshopLoader.m?spec=svn28&r=11#107
Die internen Modelle sind bestenfalls verrückt, als würde jemand das Schema in ein Boggle-Spiel stecken, es versiegeln und in einen Paint-Shacker stecken ...
Reale Welt: Ich arbeite an einer Midware-Fulfillment-App und hier sind einige Fragen, um Adressinformationen zu erhalten.
CREATE OR REPLACE VIEW sales_flat_addresses AS
SELECT sales_order_entity.parent_id AS order_id,
sales_order_entity.entity_id,
CONCAT(CONCAT(UCASE(MID(sales_order_entity_varchar.value,1,1)),MID(sales_order_entity_varchar.value,2)), "Address") as type,
GROUP_CONCAT(
CONCAT( eav_attribute.attribute_code," ::::: ", sales_order_entity_varchar.value )
ORDER BY sales_order_entity_varchar.value DESC
SEPARATOR '!!!!!'
) as data
FROM sales_order_entity
INNER JOIN sales_order_entity_varchar ON sales_order_entity_varchar.entity_id = sales_order_entity.entity_id
INNER JOIN eav_attribute ON eav_attribute.attribute_id = sales_order_entity_varchar.attribute_id
AND sales_order_entity.entity_type_id =12
GROUP BY sales_order_entity.entity_id
ORDER BY eav_attribute.attribute_code = 'address_type'
Genaue Adressangaben für eine Bestellung, träge
-
Zusammenfassung: Verwenden Sie Magento nur, wenn:
Wenn die Leistung keine große Anforderung ist, wie bei einer ETL-Anwendung, hat EAV einen weiteren entscheidenden Vorteil: Differential Save.
Ich habe eine Reihe von Anwendungen implementiert, bei denen eine übergeordnete Anforderung darin bestand, den Verlauf eines Domänenobjekts von der ersten "Version" bis zum aktuellen Status anzuzeigen. Wenn dieses Domänenobjekt eine große Anzahl von Attributen aufweist, bedeutet dies, dass für jede Änderung eine neue Zeile in die entsprechende Tabelle eingefügt werden muss (keine Aktualisierung, da der Verlauf verloren gehen würde, sondern eine Einfügung). Nehmen wir an, dieses Domain-Objekt ist eine Person, und ich habe 500.000 Personen mit durchschnittlich über 100 Änderungen über den Lebenszyklus der Personen in verschiedenen Attributen zu verfolgen. Wenn Sie dies mit der Tatsache verbinden, dass es sich bei der Anwendung um eine seltene Anwendung handelt, die nur ein Hauptdomänenobjekt enthält, können Sie schnell davon ausgehen, dass die Größe der Datenbank schnell außer Kontrolle geraten würde.
Eine einfache Lösung besteht darin, nur die unterschiedlichen Änderungen an den Hauptdomänenobjekten zu speichern, anstatt wiederholt redundante Informationen zu speichern.
Alle Modelle ändern sich im Laufe der Zeit, um neuen Geschäftsanforderungen Rechnung zu tragen. Zeitraum. Die Verwendung von EAV ist nur eines der Tools in unserer Box. Es sollte jedoch niemals automatisch als "schlecht" eingestuft werden.
Ich habe mit dem gleichen Problem zu kämpfen. Es kann für Sie interessant sein, die folgende Diskussion über zwei vorhandene E-Commerce-Lösungen zu lesen: Magento (EAV) und Joomla (reguläre relationale Struktur): https://forum.virtuemart.net/index.php?topic=) 58686.
Es scheint, dass Magentos EAV-Performance ein echter Showstopper ist.
Deshalb neige ich zu einer normalisierten Struktur. Um den Mangel an Flexibilität zu überwinden, denke ich darüber nach, in Zukunft ein separates Datenwörterbuch (XML oder separate DB-Tabellen) hinzuzufügen, das bearbeitet werden könnte, und basierend darauf wäre Anwendungscode zum Anzeigen und Vergleichen von Produktkategorien mit neuen Attributen festgelegt zusammen mit SQL-Skripten generiert.
Eine solche Architektur scheint in diesem Fall der Sweetspot zu sein - flexibel und performant zugleich.
Das Problem könnte die häufige Verwendung von ALTER TABLE in einer Live-Umgebung sein. Ich verwende Postgres, daher werden MVCC und Transaktions-DDL hoffentlich die Schmerzen lindern.
Ich stimme immer noch für die Modellierung auf der niedrigstwertigen atomaren Ebene für EAV. Überlassen Sie Standards, Technologien und Anwendungen, die sich an bestimmte Benutzer richten, die Entscheidung über Inhaltsmodelle, Wiederholungsanforderungen von Attributen, Körnungen usw.
Wenn es nur um die Produktkatalogattribute geht und die Validierungsanforderungen für diese Attribute daher eher begrenzt sind, besteht der einzige wirkliche Nachteil von EAV in der Abfrageleistung, und selbst das ist nur dann ein Problem, wenn Ihre Abfrage mehrere "Dinge" (Produkte) mit Attributen behandelt. Die Leistung für die Abfrage "Gib mir alle Attribute für das Produkt mit der ID 234" ist zwar nicht optimal, aber dennoch ausreichend schnell.
Eine Lösung besteht darin, das SQL-Datenbank-/EAV-Modell nur für die Administrations-/Bearbeitungsseite des Produktkatalogs zu verwenden und einen Prozess zu verwenden, der die Produkte in etwas denormalisiert, das sie durchsuchbar macht. Da Sie bereits Attribute haben und es daher sehr wahrscheinlich ist, dass Sie eine Facettierung wünschen, kann dies Solr oder ElasticSearch sein. Dieser Ansatz vermeidet im Grunde alle Nachteile des EAV-Modells und die zusätzliche Komplexität beschränkt sich auf die Serialisierung eines vollständigen Produkts auf JSON beim Update.
EAV hat viele Nachteile:
Ich habe ein etwas anderes Problem: Anstelle vieler Attribute mit spärlichen Werten (was möglicherweise ein guter Grund ist, EAV zu verwenden) möchte ich etwas mehr wie eine Tabelle speichern. Die Spalten im Arbeitsblatt können sich ändern, aber innerhalb eines Arbeitsblatts enthalten alle Zellen Daten (nicht spärlich).
Ich habe eine kleine Reihe von Tests durchgeführt, um zwei Designs zu vergleichen: eines mit EAV und das andere mit einem Postgres ARRAY zum Speichern von Zelldaten.
Beide Schemata haben Indizes für entsprechende Spalten, und die Indizes werden vom Planer verwendet.
Es stellte sich heraus, dass das Array-basierte Schema um eine Größenordnung schneller war sowohl für Einfügungen als auch für Abfragen. Aus schnellen Tests ging hervor, dass beide linear skalierten. Die Tests sind jedoch nicht sehr gründlich. Vorschläge und Gabeln sind willkommen - sie stehen unter einer MIT Lizenz.