Ich muss dynamische Felder und Werte in einem großen Datawarehouse für das Speichern des API-Anforderungsprotokolls unterstützen. Mein Anwendungsfall ist, dass ich alle API-Anforderungs-Abfragezeichenfolgen speichern und in der Lage sein muss, in Zukunft eine Abfrage für sie durchzuführen (es handelt sich also nicht nur um die Speicherung. Also kann ich keinen Blob für sie verwenden.)
z.B http://example.com/?action=test&foo=abc&bar=def...
Ich muss alle field => value
Zuordnungen speichern , dh (action => test), (foo => abc), (bar => def)
, da das Feld so dynamisch ist, habe ich nur die Lösung gefunden, Entity-Attribute-Value zu verwenden. Es wird jedoch immer wieder behauptet, dass es sich um ein sehr schlechtes Design handelt.
Betrachten Sie also meinen obigen Anwendungsfall, was wäre eine geeignete Alternative zu EAV?
Mein aktuelles Schema mit KAV
Tisch
requests
(id, timestamp, uri)
zB(1, 149382220, '/')
Tisch
params
(request_id, key, value)
zB(1, 'action', 'test'), (1, 'foo', 'abc'), (1, 'bar', 'def')
Irgendwelche Vorschläge?
Update: Wir führen das Warehouse auf AWS RedShift aus
SQL
ist nicht spezifisch genug. Du wurdest zweimal gefragt. Ich bin der drittehstore
oderjson
Datentypen (oderjsonb
ob / wann sie „Upgrade“ auf 9,4).Antworten:
Ich kann mir drei Lösungen vorstellen - EAV, XML und Sparse Columns. Letzteres ist herstellerspezifisch und für Sie möglicherweise nicht hilfreich.
Unabhängig von der gewählten Methode können Sie die ursprünglichen Anforderungsdaten in einem unformatierten Format, in einer Tabelle oder in einer Einfachdatei speichern. Sie können auf einfache Weise neue Möglichkeiten zum Speichern der Daten ausprobieren, Daten neu laden, wenn Sie einen Fehler beim Parsen Ihrer Anforderungen feststellen, und die API-Anforderungen mithilfe von Stapelverarbeitung oder "Big Data" analysieren. Tools, wenn Sie feststellen, dass Ihr Data Warehouse die Daten nicht effizient verarbeiten kann.
Überlegungen zur EAV
EAV / KVS, wie Sie es oben beschrieben haben, ist wahrscheinlich die einfachste Implementierung.
Leider wird es auch sehr teuer - um effiziente Abfragen zu häufig verwendeten Schlüsseln zu erhalten, benötigen Sie Indizes in der Schlüsselspalte, die sehr fragmentiert werden können. Das Abfragen bestimmter Schlüssel wäre extrem teuer.
Möglicherweise können Sie die Kosten für die Indizierung oder Indexsuche senken, indem Sie Ihren EAV-Speicher mit materialisierten Ansichten (viele Anbieter unterstützen dies) zum Abfragen von Schlüsseln oder Werten unterstützen, die Sie interessieren.
XML
Die meisten Unternehmensdatenbanksysteme bieten eine sehr ausgereifte XML-Verarbeitung, einschließlich Validierung, Indizierung und komplexer Abfragen.
Wenn Sie die API-Anforderung als XML in die Datenbank laden, erhalten Sie ein Tupel pro Anforderung. Dies ist logischerweise für Sie möglicherweise etwas angenehmer als eine unbekannte Anzahl von Zeilen in einer EAV-Tabelle.
Ob dies effizient ist, hängt stark von Ihrem RDBMS-Anbieter und Ihrer Implementierung ab.
Der größte Nachteil ist, dass dies wahrscheinlich die einzige Möglichkeit ist, Daten zu verwalten, die komplizierter ist als die Manipulation von Zeichenfolgen der ursprünglichen Anforderung!
Sparse Columns / traditionelle Tische
Es ist möglich, dass Sie Ihre Daten in eine herkömmliche Tabellenstruktur mit einer Spalte pro Schlüssel laden.
Die Funktion " Sparse Columns" von SQL Server ist eine hervorragende Alternative zu einem EAV-Speicher. Eine Tabelle mit Spalten mit geringer Dichte verhält sich ähnlich wie eine normale Tabelle, außer dass sie bis zu 30.000 Spalten enthalten kann und NULL-Werte in Spalten mit geringer Dichte keinen Speicherplatz in der Tabelle belegen.
Die Kombination mit gefilterten Indizes (eine weitere SQL Server-spezifische Funktion) kann eine äußerst effiziente Alternative zu einem EAV-Speicher darstellen, wenn Sie häufig nach bestimmten Spalten und / oder Werten fragen.
Die Verwendung einer herkömmlichen Tabelle mit anderen Anbietern kann sinnvoll sein - IBM unterstützt über 700 Spalten pro Tabelle und Oracle etwa 1000. Funktionen wie die Komprimierung oder die Behandlung von nachgestellten Nullen durch Oracle können dazu führen, dass Sie Ihre API-Daten relativ effizient speichern können.
Der offensichtliche Nachteil dieses Ansatzes ist, dass Sie beim Hinzufügen neuer Schlüssel zu Ihrer API Ihr Schema entsprechend anpassen müssen.
quelle
hstore
oder nicht empfehlenjson
. Im kommenden 9.4jsonb
wäre meine Empfehlung.EAV ist an sich kein schlechtes Design, es ist einfach ein Design, das eine angemessene Menge an Voraussicht erfordert und mit Leistungsproblemen bewerkstelligt werden kann, wenn die Datenmenge steigt. Es kann sein, dass es für Ihr System gut funktionieren würde.
Als ich ein System zum Speichern von Abfragezeichenfolgen entwarf, hatte ich keine Ahnung , welche Felder mich interessieren würden. Ich erstellte eine Tabelle zum Speichern der Abfragezeichenfolge im serialisierten Binärformat und erstellte ein System, mit dem ich die Abfrage aufteilen konnte Zerlegen Sie die Teile in Einzelteile, sobald ich die Teile kannte, an denen ich interessiert war. Von dort aus erstellte ich eine Reihe von Tabellen. jeweils eine für die Datensätze, die üblicherweise in der Abfragezeichenfolge enthalten sind.
Zum Beispiel hatte ich irgendwann eine Tabelle für Verweisdaten, eine für Zielanforderungsdaten und eine für benutzerbezogene Elemente wie die von ihnen eingegebene Suchabfrage.
Ich fand die Möglichkeit, die gesamte Abfragezeichenfolge in einer einzelnen Tabelle als Blob zu speichern, und die Möglichkeit, diesen Blob in Zukunft aufzuteilen, erfüllte meine Anforderungen sehr gut.
quelle
BLOB
verwendet, der Binary Long OBject bedeutet. Ich würde es vorziehen, einCLOB
(Character Long OBject) oder ähnlichestext
in PostgreSQL zu verwenden, da es sich um Zeichen und nicht um Binärdaten handelt.