it-swarm.com.de

Timeseries: SQL oder NoSQL?

Die allgemeinen Unterschiede zwischen SQL und NoSQL (oder ihre traditionellen Unterschiede) sind mir egal.

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 gegenü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 organisiert:/Markt/Instrument/Wert/Häufigkeit, wobei:

  • Der Markt ist eine Wertpapierbörse usw., im Grunde genommen eine Sammlung von Instrumenten, normalerweise ähnliche Instrumente.
  • Instrument ist ein Instrument. Dies kann ein Indikator (Brent Crude), ein Eigenkapital (toget) usw. Sein
  • Der Wert ist einer von mehreren Datentypen für ein Instrument. Dies kann ein enger, hoher, niedriger usw. Sein
  • Die Frequenz ist die Frequenz eines bestimmten Zeitreihenwerts. Wöchentlich, täglich, monatlich, ankreuzen, willkürlich 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.

Vielen Dank im Voraus.

33
Nicolas

Im Allgemeinen könnten Sie für einen derart strukturierten Datensatz ein benutzerdefiniertes Datenformat schreiben, das für die meisten täglichen Vorgänge schneller war (d. H. Kleine Daten werden aus einer beliebigen Zeit abgerufen). Der Vorteil der Umstellung auf ein Standard-DB-Tool liegt wahrscheinlich in einigen Extras, z. B. Ad-hoc-Abfragen, Mehrfachzugriff, Replikation, Verfügbarkeit usw. Es ist auch einfacher, Hilfe für die Verwaltung eines standardbasierten Datenspeichers zu mieten.

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 eingefügt:

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

Diese Tabellen werden ziemlich groß, und Sie können sie manuell nach (zum Beispiel) Jahr partitionieren. Sie müssen jedoch die Systemleistung überprüfen und entsprechend einstellen.

Diese Tabellen benötigen eindeutige Namen, und es gibt mehrere Optionen. Sie können von Menschen lesbar (z. B. nyse_goog_dailyhighs_2010) oder (nach meiner Präferenz) zufällig sein. In beiden Fällen ist eine Reihe von Metadatentabellen erforderlich, und zufällige Tabellennamen verhindern, dass Entwickler etwas in den Namen ableiten, 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 andere, was Sie benötigen. Diese werden Datentabellennamen zugeordnet.

Wenn genügend Daten vorhanden sind, kann diese Suche tatsächlich einen Tabellennamen und einen Datenbanknamen enthalten, was eine Art selbst implementiertes Daten-Sharding ermöglicht (wenn dies die korrekte Verwendung des Begriffs ist). Aber ich würde das in Reserve halten.

Dann habe ich auf Anwendungsebene die Metadatentabellen abgefragt, um festzustellen, wo sich meine Daten befinden, und dann relativ einfache Abfragen an den 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/erneutes Laden von Sicherungen, Hinzufügen einer neuen Entität). Dadurch werden die verschiedenen Datentypen vollständig entkoppelt, 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 meiner Meinung nach 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, das Mainstream genug ist, um auf meine Karriere zu setzen. Dieses Schema kommt ziemlich nahe.

Nachteile :

  • Etwa die Hälfte Ihres Speicherplatzes ist für das Speichern von Zeitstempeln vorgesehen, wenn ehrlich gesagt 100 oder 1000 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 erfordert viel Anwendungskomplexität und Zeichenfolgenoperationen, was mich erschreckt. Aber es scheint immer noch besser als die Alternativen (unten diskutiert).

Überlegungen :

  • Achten Sie auf Rundungen 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 unbeliebt machen könnte) 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 jetzt auf die Zeit der ersten Datenspalte, und die anderen Datenspalten werden mit gleichem Abstand zwischen diesem Zeitstempel und dem nächsten angenommen. Dies spart viel Speicherplatz, der zuvor zum Speichern von Zeitstempeln verwendet wurde, und kostet erhebliche Abfrage- und/oder Anwendungskomplexität. Abfragen für zusammenhängende Bereiche und einzelne 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 Abfragen einzelner Entitäten jetzt erheblich mehr Festplattenzugriff.

Mega-Tabelle: Nehmen Sie das "Multi-Plexing" -Konzept auf die Spitze und fügen Sie alle Daten in einer einzigen Tabelle zusammen, einmal Zeitreihen pro Spalte. Dies erfordert große Mengen an Festplattenzugriff für zusammenhängende Bereiche, Abfragen einzelner Entitäten und ist ein Wartungs-Albtraum. Zum Hinzufügen einer neuen Entität ist jetzt beispielsweise der Befehl MODIFY TABLE für eine Tabelle mit vielen TB) erforderlich.

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, in der die Spalten time, dataid und sind Wert. Jetzt müssen Ihre Metadatentabellen nur noch ID-Werte anstelle von Tabellennamen oder Spaltennamen nachschlagen, wodurch mehr Logik in die SQL-Abfragen als in die Anwendungsschicht übertragen werden kann.

Ungefähr 2/3 des Speichers werden jetzt mit den normalisierenden Spalten belegt, sodass viel Speicherplatz benötigt wird.

Sie können eine Primärschlüsselreihenfolge von (Daten-ID, Zeitstempel) für schnelle zusammenhängende Abfragen einzelner Entitäten verwenden. Oder Sie können eine Primärschlüsselreihenfolge von (Zeitstempel. Dataid) für schnellere Einfügungen verwenden.

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

26
Pursuit

Mit MongoDB können Sie Sammlungen sehr schnell im laufenden Betrieb erstellen. Sehen Sie sich an, wie Sie Ihre Daten in separaten Datenbanken und Sammlungen in diesen Datenbanken anordnen. Überlegen Sie, wie viel Speicher Sie benötigen würden, um jeden Shard im Systemspeicher zu halten - wenn Sie einen schnellen Abruf benötigen. Es ist albern, sich an eine interne Lösung zu halten, wenn es etwas Frischeres gibt, das sich nach Ihren Vorstellungen entwickelt. Klingt nach einer guten Initiative.

1
Dantalion