Timeseries: SQL oder NoSQL?


33

Die allgemeinen Unterschiede zwischen SQL und NoSQL (oder ihre traditionellen Unterschiede) interessieren mich nicht.

Ich bin gerade dabei, die Speicherung unserer internen Zeitreihen zu ändern. Sie alle enthalten Finanzdaten aus verschiedenen Quellen. Derzeit speichern wir unsere Daten in einer proprietären Datenbank. Es ist sehr viel NoSQL, das eine eigene Abfragesprache hat.

Ich interessiere mich für die Community-Eingabe: Wie würden Sie die Daten in einer SQL-Datenbank speichern? Welche Vorteile bietet die Verwendung von SQL über NoSQL, insbesondere für Zeitreihen? Bin ich verrückt, wenn ich erwäge, dies in SQL zu speichern?

Unser Datensatz besteht aus Millionen von Zeitreihen, von denen etwa 10% jeweils Millionen von Datensätzen enthalten. Die Zeitreihen sind hierarchisch gegliedert: / Markt / Instrument / Wert / Häufigkeit, wobei:

  • Markt ist eine Wertpapierbörse usw., im Grunde eine Sammlung von Instrumenten, normalerweise ähnliche Instrumente.
  • Instrument ist ein Instrument. Dies kann ein Indikator (Brent Crude), ein Eigenkapital (paragraph) usw. Sein
  • Der Wert ist einer von mehreren Datentypen für ein Instrument. Dies kann eine enge, hohe, niedrige usw. Sein
  • Frequenz ist die Frequenz eines bestimmten Zeitreihenwertes. Wöchentlich, täglich, monatlich, ankreuzen, beliebig usw.

Wie würden die Daten in einer SQL-Datenbank gespeichert? Ein großer Tisch (möglicherweise durch etwas unterteilt), ein Tisch pro Markt oder Instrument, ein Tisch pro Zeitreihe.

Danke im Voraus.


1
Enthalten alle Zeitreihen die gleichen Metadaten (dh Spalten)?
Jack Douglas

1
Klingt wie ein Data Warehouse ... Siehe SO: stackoverflow.com/q/2684462/27535
gbn

@ jack-douglas: fragst du das, um einen spaltenorientierten datenspeicher vorzuschlagen?
Nicolas

3
@Nicolas Nein, ich gehe davon aus, dass ein herkömmliches SQL-RDBMS für Ihre Daten gut geeignet ist, da a) die Abfrage einfacher ist, b) die Volumes nicht unpraktisch groß klingen (Milliarden von Zeilen?) C) die Partitionierung von Daten natürlich klingt und / oder Standard-OLAP-Funktionen. Ich habe nach den Metadaten gefragt, um festzustellen, wie viele Tabellen Sie benötigen. Wenn jede Zeitreihe eindeutige Metadaten enthält, benötigen Sie Millionen von Tabellen, was in einem regulären RDBMS nicht nach einer guten Idee klingt, aber ich glaube, Sie brauchen das nicht, oder?
Jack Douglas

2
@Nicolas hast du dir den neuen Hadoop Connector für SQL Server angeschaut . An der Oberfläche scheint Ihr Szenario zu passen.
Mark Storey-Smith

Antworten:


26

Ich vermute, dass Sie für einen solchen strukturierten Datensatz ein benutzerdefiniertes Datenformat schreiben können, das für die meisten täglichen Vorgänge schneller ist (dh kleine Datenmengen aus einer beliebigen Zeit). Der Vorteil der Umstellung auf ein Standard-DB-Tool ist wahrscheinlich in einigen Extras zu sehen, z. B. bei Ad-hoc-Abfragen, Mehrfachzugriff, Replikation, Verfügbarkeit usw. Es ist auch einfacher, Hilfe bei der Pflege eines auf Standards basierenden Datenspeichers anzustellen.

Wenn ich gebeten würde, eine Datenbank zum Speichern dieser Daten einzurichten, würde ich Folgendes tun:

Vorgeschlagenes Schema

(1) Kerndaten werden in zahlreiche (1000) einzelne Tabellen mit jeweils zwei Spalten platziert:

  1. Zeit: entweder ein SQL DATETIME-Datentyp oder ein numerischer Typ aus einer bestimmten Epoche (dies ist der Primärschlüssel)
  2. value: entsprechend Ihren Daten eingegeben. Ich würde standardmäßig Gleitkommazahlen mit einfacher Genauigkeit verwenden, jedoch ist ein Festkomma-Datentyp für Finanztransaktionen möglicherweise geeigneter. Dies ist wahrscheinlich nicht indiziert.

Diese Tabellen werden sehr groß, und Sie möchten sie möglicherweise manuell nach (z. B.) Jahren partitionieren. Sie müssen jedoch die Systemleistung überprüfen und gegebenenfalls abstimmen.

Diese Tabellen benötigen eindeutige Namen, und es gibt einige Optionen. Sie können von Menschen lesbar sein (z. B. nyse_goog_dailyhighs_2010) oder (nach meiner Präferenz) zufällig. In beiden Fällen ist ein Satz von Metadatentabellen erforderlich, und zufällige Tabellennamen verhindern, dass Entwickler etwas auf den Namen schließen, das nicht abgeleitet werden sollte.

(2) Metadaten werden in separaten Tabellen gespeichert, wie von der Anwendung gefordert :

Eine zusätzliche Tabelle oder ein Satz von Tabellen ist erforderlich, um die Metadaten zu verfolgen. Diese Tabellen enthalten Daten zu Austausch, Instrument, Wert, Häufigkeit, Datumsbereichen, Herkunft (woher stammen die Daten) sowie alles, was Sie sonst noch benötigen. Diese werden Datentabellennamen zugeordnet.

Wenn genügend Daten vorhanden sind, kann diese Suche tatsächlich einen Tabellennamen und einen Datenbanknamen enthalten, wodurch eine Art von selbstimplementiertem Daten-Sharding möglich wird (sofern dies die korrekte Verwendung des Begriffs ist). Aber ich würde das zurückhalten.

Auf der Anwendungsebene habe ich dann die Metadatentabellen abgefragt, um festzustellen, wo sich meine Daten befinden. Anschließend habe ich relativ einfache Abfragen für die Big-Data-Tabellen durchgeführt, um meine Daten abzurufen.

Vorteile:

  • Meine (relativ begrenzte) Erfahrung ist, dass Datenbanken im Allgemeinen eine große Anzahl kleiner Tabellen einfacher verarbeiten können als eine kleinere Anzahl großer Tabellen. Dieser Ansatz ermöglicht auch eine einfachere Wartung (z. B. Löschen alter Daten, Neuerstellen einer beschädigten Tabelle, Erstellen / Neuladen von Sicherungen, Hinzufügen einer neuen Entität). Dies entkoppelt die verschiedenen Arten von Daten vollständig, wenn Sie beispielsweise Daten mit unterschiedlichen Raten haben oder unterschiedliche Datentypen benötigen.

  • Dieses Skinny-Table-Konzept sollte auch einen schnellen Festplattenzugriff für die von mir vermutete häufigste Abfrage ermöglichen, einen zusammenhängenden Datenbereich von einer einzelnen Entität. Die meisten Datenanwendungen sind auf Festplatten-E / A beschränkt, daher ist dies eine Überlegung wert. Wie ein Kommentator bereits angedeutet hat, ist dies eine ideale Anwendung für eine spaltenorientierte Datenbank, aber ich habe noch kein spaltenorientiertes Produkt gefunden, auf das ich meine Karriere wetten kann. Dieses Schema kommt ziemlich nahe.

Nachteile:

  • Etwa die Hälfte Ihres Speicherplatzes ist für die Speicherung von Zeitstempeln vorgesehen, wenn offen gesagt 100er oder 1000er der Tabellen genau dieselben Daten in der Zeitstempelspalte enthalten. (Tatsächlich ist dies eine Voraussetzung, wenn Sie einfache Tabellenverknüpfungen durchführen möchten.)

  • Das Speichern von Tabellennamen und das Durchführen der dynamischen Suche erfordern viel Anwendungskomplexität und Zeichenfolgenoperationen, was mich erschreckt. Aber es scheint immer noch besser zu sein als die Alternativen (siehe unten).

Überlegungen:

  • Achten Sie auf die Rundung in Ihrem Zeitfeld. Sie möchten, dass Ihre Werte rund genug sind, um Verknüpfungen zu ermöglichen (falls zutreffend), aber präzise genug, um eindeutig zu sein.

  • Achten Sie auf Zeitzonen und Sommerzeit. Diese sind schwer zu testen. Ich würde eine UTC-Anforderung für den Datenspeicher erzwingen (was mich möglicherweise unbeliebt macht) und Konvertierungen in der Anwendung verarbeiten.

Variationen:

Einige Variationen, die ich in Betracht gezogen habe, sind:

Datenfaltung : Wenn die Zeitreihen gleichmäßig verteilt sind, verwenden Sie eine Zeitstempelspalte und (zum Beispiel) 10 Datenspalten. Der Zeitstempel bezieht sich nun auf die Zeit der ersten Datenspalte, und es wird angenommen, dass die anderen Datenspalten einen gleichen Abstand zwischen diesem Zeitstempel und dem nächsten aufweisen. Dies spart viel Speicherplatz, der zuvor zum Speichern von Zeitstempeln verwendet wurde, und ist mit erheblichen Kosten für die Abfrage und / oder die Komplexität der Anwendung verbunden. Abfragen für zusammenhängende Bereiche einzelner Entitäten erfordern jetzt weniger Festplattenzugriff.

Multi-Plexing: Wenn bekannt ist, dass mehrere Zeitreihen dieselbe Zeitreihe verwenden, verwenden Sie einen Zeitstempel und (zum Beispiel) 10 Datenspalten, wie oben beschrieben. Jetzt repräsentiert jede Spalte eine andere Zeitreihe. Dies erfordert eine Aktualisierung der Metadatentabelle, bei der es sich nicht um eine Suche nach Tabellen- und Spaltennamen handelt. Speicherplatz wird reduziert. Abfragen bleiben einfach. Unabhängig vom zusammenhängenden Bereich erfordern Einzelentitätsabfragen jetzt erheblich mehr Festplattenzugriff.

Mega-Tabelle: Bringen Sie das "Multi-Plexing" -Konzept auf die Spitze und fassen Sie alle Daten einmal pro Spalte in einer Tabelle zusammen. Dies erfordert umfangreiche Datenträgerzugriffe für zusammenhängende Bereiche und Abfragen einzelner Entitäten und ist ein Wartungs-Albtraum. Beispielsweise erfordert das Hinzufügen einer neuen Entität jetzt einen Befehl MODIFY TABLE für eine Tabelle mit vielen TB.

Weitere Informationen zu diesem Format finden Sie in den verschiedenen Antworten unter: Zu viele Spalten in MySQL

Vollständig normalisierte Tabelle: Anstatt viele zweispaltige Tabellen zu verwenden, können Sie auch eine dreispaltige Tabelle verwenden, deren Spalten Zeit, Daten-ID und Wert sind. Jetzt müssen Ihre Metadatentabellen nur noch nach ID-Werten anstatt nach Tabellennamen oder Spaltennamen suchen, wodurch mehr Logik in die SQL-Abfragen als in die Anwendungsebene übertragen werden kann.

Etwa 2/3 des Speichers wird jetzt mit den normalisierenden Spalten belegt, sodass dies viel Speicherplatz beansprucht.

Sie können die Primärschlüsselreihenfolge (Daten-ID, Zeitstempel) für schnelle zusammenhängende Einzelentitätsabfragen verwenden. Alternativ können Sie für schnellere Einfügungen die Primärschlüsselreihenfolge (timestamp. Dataid) verwenden.

Trotz dieser Variationen sind für meine nächste Entwicklung viele Tabellen mit jeweils zwei Spalten geplant. Das oder die Methode wird bald von jemandem gepostet, der klüger ist als ich :).


Ich danke Ihnen sehr für Ihre Antwort. Sie haben einige sehr gültige Punkte angesprochen. Ich bin mit der Speicherung in UTC völlig einverstanden. Ich setze die Idee durch, dass alle Daten in UTC an die Frontends (Web, Desktop & Mobile) geliefert werden. Wir haben multinationale Kunden, und das Betriebssystem sollte für die Zeitumstellung verantwortlich sein. Ich habe eine DBA-Firma, die an unserem gesamten Datensatz arbeitet, und ich habe mich gefragt, was die anderen wohl machen würden. Danke noch einmal.
Nicolas

Während die DBA-Berater an einer fehlerhaften SQL Server-Installation arbeiten, werde ich mit dem Testen eines BigData-Setups fortfahren.
Nicolas

Möglicherweise ist dies eine gute Lösung, aber die Echtzeitanwendung "Zeitreihen" sollte die Funktion "In Daten zoomen" unterstützen, und die Datenbank kann dabei nicht helfen. Bei Zeitreihendatenbanken geht es eher um cleveres "Vergrößern" und "Verkleinern".
Roman Pokrovskij

1

Mit MongoDB können Sie Sammlungen sehr schnell erstellen. Sehen Sie sich an, wie Sie Ihre Daten in separaten Datenbanken und Sammlungen innerhalb dieser Datenbanken anordnen. Überlegen Sie, wie viel Speicher Sie benötigen würden, um jeden Shard im Systemspeicher zu belassen - wenn Sie einen schnellen Abruf benötigen. Es ist dumm, bei einer internen Lösung zu bleiben, wenn es etwas Frischeres gibt, das sich in den von Ihnen gewünschten Richtungen entwickelt. Klingt nach einer guten Initiative.


2
Wie würden Sie die Zeitreihen in Mongo speichern? Jedes Dokument ist eine Zeitreihe? oder der Wert eines bestimmten Zeitstempels?
RockScience

Um dies effizient für nicht-periodische oder sogar periodische Daten durchzuführen, ist es am besten, Datenblöcke vorab zuzuweisen. Jeder Block wäre ein Dokument mit einer kleinen Menge von Buchhaltungsdaten, einem Array mit fester Größe für Ihre Werte und einem Array mit fester Größe für Ihre Zeit. Sie würden dann Ihre Metadaten für die Serie in einem separaten Dokument speichern. Verwalten Sie in diesem Metadatendokument ein kleines verschachteltes Dokument, das als Buchhalter für Ihre Datensegmente fungiert, dh verfolgen Sie den aktuellen Array-Index und die Segment-ID.
RYS
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.