Was ist ein guter Weg, um eine große Anzahl von Spalten zu speichern?

18

Ich habe ein Problem bei der Entscheidung, wie diese Daten in meiner Datenbank gespeichert werden sollen. Irgendwelche Vorschläge, wie es am besten geht? Ich weiß nicht viel über Datenbanken, könnte ich hinzufügen.

Ich habe Daten, die wie folgt formatiert eingehen, aber anstelle von 4 ist die Anzahl der Spalten ungefähr 240, sodass mit jedem Datum 240 eindeutige Werte verknüpft sind:

Date/Time 200,00 202,50 205,00  
2010.11.12  13:34:00  45,8214 43,8512  41,5369   
2010.11.12  13:35:00  461,9364  454,2612  435,5222 

Außerdem werden Zeilen mit DataSites verknüpft.

Mein erster Gedanke war, eine Tabelle wie diese zu haben: DataID (pk), DataSiteID, ParameterID, Datum, Wert mit einem Index für DataSite, Parameter und Datum. Die ParameterID verweist auf eine andere Tabelle, in der die Kopfzeilen der Eingabespalten gespeichert sind (200,00 202,50 205,00 ...).

Mein zweiter Gedanke war einfach, eine Tabelle mit allen 240 ungeraden Spalten zu haben. Ich habe mir ein paar andere Möglichkeiten ausgedacht, aber sie sind auch ziemlich unbefriedigend.

Das Problem, das ich bei meiner ersten Lösung habe (kein so großes Problem, aber es gefällt mir nicht), ist, dass das Datum und die DataSiteID für alle 240 Werte in dieser Eingabezeile wiederholt werden, sodass sie ziemlich viel verwenden zusätzlichen Platz.

Pro Jahr werden ca. 40 GB Daten (im obigen Textformat) eingehen, und die Daten werden nach DataSite, Parameter und Datum durchsucht. Die Menge der eingehenden Daten wird sich höchstwahrscheinlich innerhalb eines Jahres vervierfachen.

Irgendwelche guten Ideen? Danke, James

Bearbeiten: Dies sind Zeitreihendaten, wobei die Spalten Messungen bei verschiedenen Wellenlängen sind. Daten sollten in einem relativ engen Wellenlängenbereich analysiert werden. Zu einem späteren Zeitpunkt könnten auch zusätzliche Wellenlängen hinzugefügt werden.

edit: Danke für die Antworten Leute, ich weiß es wirklich zu schätzen :) Ich denke, ich kann wahrscheinlich Zeit finden, einige Experimente mit etwa 500 GB Testdaten durchzuführen. Ich werde mit irgendwelchen Schlussfolgerungen zurückschicken;)

James
quelle
2
Die Benennung der Spalten lässt vermuten, dass dies eine Art Beobachtungszeitreihendaten ist. Wenn es sich um wissenschaftliche Daten handelt, würde ich prüfen, ob die wissenschaftliche Disziplin über typische Methoden zur Organisation ihrer Daten verfügt, oder zumindest, welche wissenschaftlichen Anwendungsfälle diese Daten verwenden.
Joe
Es handelt sich in der Tat um Zeitreihendaten :) Originalbeitrag bearbeitet mit ein bisschen mehr Info.
James

Antworten:

10

Sie könnten einen Fall so oder so machen, aber wenn die Daten für die Analyse verwendet werden sollen und Sie häufig mehrere Spalten dieser Daten gleichzeitig sehen möchten, wählen Sie die breite Tabelle. Stellen Sie sicher, dass Sie die Grenzwerte für die Spaltenanzahl und die Zeilengröße Ihrer Datenbank kennen. Stellen Sie sicher, dass Sie die richtigen Datentypen haben. Wenn viele der Spalten NULL sind, können Sie mit SQL Server die Tabelle dafür optimieren. Sie können auch eine NOSQL-Lösung (Not Only SQL) zur Analyse dieser Art von Daten verwenden.

Wenn diese Daten für die Analyse geringer sind, können Sie sie wie in Ihrer Frage angegeben normalisieren.

Eric Humphrey - Lotsahelp
quelle
6

Ich hatte eine sehr ähnliche Situation wie Sie, 257 Felder mit 30-50 GB pro Jahr. Am Ende habe ich es einfach gehalten, eine lange große Tabelle in SQL Server. Meine Daten wurden ein gutes Stück abgefragt, aber hauptsächlich auf Datum und es hat gut funktioniert.

Ich hätte die Daten in logische kleinere Spannfutter zerlegen können (Gruppen von 50 oder so), aber in diesem Fall war das wirklich kein großer Vorteil, so dass ich mir die Mühe ersparte.

Wenn ich jetzt Lust hätte, könnte ich eine NoSQL-Option in Betracht ziehen, die theoretisch besser passt, aber bei geschäftskritischen Daten ist das Ausprobieren neuer Dinge nicht immer gut für die Nerven.

henry.oswald
quelle
6

Um meine eigene Frage nachträglich zu beantworten (das Projekt ging am Ende nie voran), füllte ich eine Testtabelle mit 500 GB Daten aus, wobei die Tabelle wie folgt angeordnet war:

Mein erster Gedanke war, eine Tabelle wie diese zu haben: DataID (pk), DataSiteID, ParameterID, Datum, Wert mit einem Index für DataSite, Parameter und Datum. Die ParameterID verweist auf eine andere Tabelle, in der die Kopfzeilen der Eingabespalten gespeichert sind (200,00 202,50 205,00 ...).

Das Datenbank-Setup war die Standard-PostgreSQL-Installation auf einem alten Dual-Core-Rechner mit 3 GB RAM. Ich habe ungefähr ein Dutzend verschiedene Abfragen ausgeführt, bei denen einfach Daten nach DataSite-Datum und ParameterID ausgewählt wurden. Dabei wurden die Daten über einen Zeitraum von 1 Stunde und 1 Tag gemittelt und neue Datenblöcke eingefügt. Die Ausführung aller Abfragen aus dem Speicher dauerte weniger als eine Sekunde. Es war sicherlich viel schneller als ich erwartet hatte und ziemlich brauchbar. Eine Sache, über die ich nicht nachgedacht hatte, war, dass mit der so indizierten Tabelle auch die Indexdatei fast 500 GB groß war, sodass eine 240 Spalten breite Tabelle mit Sicherheit viel Speicherplatz einsparen würde.

James
quelle
Bei gleichzeitiger Platzersparnis hätte sich dies jedoch mit Sicherheit auf die Indexierungsgeschwindigkeit ausgewirkt. Sie könnten es noch einmal versuchen, wenn Sie die Gelegenheit dazu haben und es drehen.
Jcolebrand
3

In Postgres würde ich dies elegant mit einem Array-Typ oder einem Varray in Oracle lösen .

Gaius
quelle
Das würde funktionieren, der einzige Haken ist, dass ich die Spaltenüberschriften für diese DataSite irgendwo speichern müsste, da die Daten ohne sie nichts bedeuten und sie variieren / ändern könnten (das sollten sie nicht, aber ich ' Ich habe Schweine fliegen gesehen, bevor ...)
James
In diesem Fall hätte ich in meiner Hauptdatentabelle eine andere Spalte namens "version" und eine andere Tabellenzuordnungsversion für ein Array von Spaltenüberschriften (die Arrayindizes stimmen also mit dem Datenarray überein).
Gaius
3

Ich weiß nicht, ob es für Ihr Problem nützlich ist, aber für die Spalten, für die ich keine direkten Anforderungen ausführen muss (Spalten, die ich nie in meine WHERE-Bedingung versetze), und die nur informativ sind, wenn ich alle Informationen zu einigen wünschen Bestimmte Zeilen kombiniere ich in einem JSON-formatierten Blogfeld.


quelle
Komprimieren Sie außerdem diesen Blob. Führen Sie die Komprimierung im Client durch, damit das Netzwerk und der Server nicht zusätzlich belastet werden.
Rick James
2

Ich würde wahrscheinlich die endgültige Entscheidung für das Design von der Verteilung der abgefragten parameter_ids abhängig machen. Das heißt, wenn es einige parameter_ids gibt, die fast ausschließlich abgefragt werden, würde ich ihre Werte in eine heiße Tabelle setzen und die restlichen Werte in eine andere kalte Tabelle stellen .

Wenn ihre Abfrageverteilung mehr oder weniger gleichmäßig ist, würde ich ein Beispielset im Wert von ein paar Tagen in eine Tabelle laden, in der ein Datensatz alle Werte enthält, um zu sehen, wie das Verhältnis zwischen Datensätzen / DB-Blöcken ist (oder wenn es gibt sogar eine Problem mit der Reihenverkettung , was wahrscheinlich ist. Abhängig davon würde ich dann eine weitere Designentscheidung treffen.

Nun, nachdem ich es gelesen habe, würde ich wahrscheinlich beide Ansätze für eine Entscheidung gleichzeitig machen.

René Nyffenegger
quelle
2

Ich habe die Frage noch einmal gelesen - wenn ich das richtig habe, werden in jedem Datensatz, den Sie als Eingabe erhalten, verschiedene Werte verfolgt (basierend auf der ParameterID):

Die ParameterID verweist auf eine andere Tabelle, in der die Kopfzeilen der Eingabespalten gespeichert sind (200,00 202,50 205,00 ...).

... Ich weiß nicht genug darüber, wie Sie mit den Daten interagieren, aber ich würde gerne eine andere Option wählen - eine separate Tabelle für jede Parameter-ID und dann, falls erforderlich, eine entsprechende Ansicht Fügen Sie die verschiedenen Parameter nach Datum und Ort in die breitere Tabelle (240 Spalten) ein. Wenn es wichtig ist, die Daten-ID in der Ansicht zugänglich zu halten, können Sie statt eines UNIONein verwenden JOIN, die Spalten werden jedoch nur spärlich gefüllt.

Joe
quelle
Mit Parameter meine ich die Spaltenüberschrift oder Wellenlänge. Ich hatte mir überlegt, es so zu machen, aber 240 Tische zu haben, fühlt sich etwas klobig an :)
James
@James ... es sollten nicht 240 Tabellen sein ... nur so viele wie die eindeutigen ParameterIDs. Die Ansicht ist dann so breit wie die Anzahl der diskreten Wellenlängen, bei denen Sie Messungen durchführen (zuzüglich der unabhängigen Variablen). ... Vielleicht möchten Sie sich ansehen, wie die OPeNDAP- Community mit Dingen umgeht , die auf Zeitreihendaten ausgerichtet sind. Die meisten Daten, mit denen ich zu tun habe, sind Bilder (Teleskope, Koronographen, Magnetographen), daher passen ihre Daten nicht zu meiner Arbeit, sodass ich nicht weiß, wie sie mit der Speicherung umgehen. (Möglicherweise handelt es sich nur um HDF / CDF / NetCDF / ASCII-Tabellen.)
Joe
Leider gibt es 240-ish eindeutige Parameter :( Danke für den Link :)
James
@ James: Sind es auch Bestrahlungsdaten? Wenn ja, möchten Sie vielleicht die Leute bei LISIRD fragen ... Ich glaube, sie teilen es durch Experimente in separate Datensätze auf, und ich weiß nicht, ob sie es in Datenbanken oder nur in Einfachdateien aufbewahren.
Joe