Hintergrund
Ich habe ein Netzwerk von ungefähr 2000 Sensoren, von denen jeder ungefähr 100 Datenpunkte hat, die wir in 10-Minuten-Intervallen sammeln. Bei diesen Datenpunkten handelt es sich normalerweise um int-Werte, bei einigen handelt es sich jedoch um Zeichenfolgen und Gleitkommazahlen. Diese Daten sollten 90 Tage gespeichert werden, wenn möglich und dennoch effizienter.
Datenbank Design
Als ich ursprünglich mit diesem Projekt beauftragt war, habe ich eine C # -App geschrieben, die kommagetrennte Dateien für jeden Sensor schrieb. Zu der Zeit gab es nicht so viele, als jemand Trends betrachten wollte, öffneten wir die CSV in Excel und zeichneten sie nach Bedarf.
Die Dinge wuchsen und wir wechselten zu einer MySQL-Datenbank. Ich habe für jeden Sensor eine Tabelle erstellt (ja, ich weiß, viele Tabellen!); Es hat gut funktioniert, aber es hat einige Einschränkungen. Bei so vielen Tabellen ist es offensichtlich unmöglich, eine Abfrage zu schreiben, die bei der Suche nach einem bestimmten Wert Daten zwischen allen Sensoren findet.
Für die nächste Version habe ich zu Microsoft SQL Server Express gewechselt und alle Sensordaten in einer großen Tabelle zusammengefasst. Dies funktioniert auch und lässt uns Abfragen durchführen, um Werte unter allen Sensoren zu finden, die von Interesse sind. Ich bin jedoch auf das 10-GB-Limit für die Express-Version gestoßen und habe beschlossen, wieder auf MySQL umzustellen, anstatt in SQL Server Standard zu investieren.
Die Frage
Ich bin mit der Leistung und Skalierbarkeit von MySQL zufrieden, bin mir aber nicht sicher, ob es am besten ist, sich an den All-Data-in-One-Table-Ansatz zu halten. 10 GB in einer einzelnen Tabelle scheinen nach einem anderen Design zu verlangen. Ich sollte erwähnen, dass die Notwendigkeit, Daten für die grafische Darstellung abzufragen, weiterhin besteht, und ich bin besorgt, dass es Leistungsprobleme bei einer Abfrage gibt, die beispielsweise Temperaturdaten für einen Sensor über die gesamten 90 Tage grafisch darstellt. (Mit anderen Worten, das Diagramm sollte schnell erstellt werden können, ohne darauf zu warten, dass SQL die Datenstapel sortiert, um den interessierenden Sensor zu isolieren.)
Sollte ich diese Tabelle in irgendeiner Weise aufteilen, um die Leistung zu steigern? Oder ist es nicht ungewöhnlich, einen so großen Tisch zu haben?
Ich habe Indizes für die Sensor-ID- und Zeitstempel-Spalten, die so ziemlich die definierenden Grenzen für jede Abfrage darstellen. (dh Daten für Sensor X von Zeitpunkt A zu Zeitpunkt B abrufen).
Ich habe ein wenig über Sharding und Partitioning gelesen, halte diese in diesem Fall jedoch nicht für angemessen.
Bearbeiten:
Aufgrund der bisherigen Kommentare und Antworten können einige zusätzliche Informationen hilfreich sein:
Nicht unbefristete Speicherung: Derzeit speichere ich keine Daten seit 90 Tagen. Täglich führe ich eine Abfrage aus, mit der Daten entfernt werden, die älter als 90 Tage sind. Wenn es in Zukunft wichtig wird, werde ich mehr speichern, aber es ist vorerst ausreichend. Dies hilft, die Größe in Schach zu halten und die Leistung hoch zu halten.
Motortyp: Die ursprüngliche MySQL-Implementierung verwendete MyISAM. Wenn die Tabellen dieses Mal für die neue Implementierung erstellt werden (eine Datentabelle anstelle von vielen), wird standardmäßig InnoDB verwendet. Ich glaube nicht, dass ich eine Anforderung für das eine oder andere habe.
Normalisierung: Neben der Datenerfassungstabelle gibt es natürlich noch weitere Tabellen. In diesen Support-Tabellen werden beispielsweise Netzwerkinformationen für die Sensoren, Anmeldeinformationen für Benutzer usw. gespeichert. Es gibt nicht viel zu normalisieren (soweit ich weiß). Der Grund, warum die Datentabelle so viele Spalten enthält, ist, dass von jedem Sensor so viele Variablen vorhanden sind. (Mehrere Temperaturen, Lichtverhältnisse, Luftdruck usw.) Normalisierung bedeutet für mich, dass es keine redundanten Daten oder sich wiederholenden Gruppen gibt. (Zumindest für 1NF.) Für einen bestimmten Sensor sind zum Speichern aller Werte zu einem bestimmten Zeitpunkt nur eine Datenzeile und keine 1: N-Beziehungen erforderlich (wie ich sehe).
Ich könnte die Tabelle funktional aufteilen und beispielsweise alle temperaturbezogenen Werte in einer Tabelle und alle luftdruckbezogenen Werte in einer anderen Tabelle angeben. Während dies die Effizienz für jemanden verbessern kann, der eine reine Temperaturabfrage durchführt, muss ich dennoch alle Daten auf einmal einfügen. Dennoch könnte sich der Effizienzgewinn für SELECT-Operationen lohnen. Offensichtlich ist es besser, die Tabelle vertikal aufzuteilen, je nachdem, wie oft Benutzer die Daten anfordern. Vielleicht ist das alles, was ich tun sollte. Wenn ich meine Frage stelle, suche ich vermutlich nach einer Bestätigung, dass es sich lohnt, dies zu tun.
Bearbeiten 2:
Datennutzung : Letztendlich wird ein Großteil der Daten nie angezeigt oder benötigt, da wir uns in der Regel nur auf problematische Elemente konzentrieren. Bei der Suche nach Problemen verwenden wir jedoch verschiedene Tools, um die Daten zu durchsuchen und zu bestimmen, welche Elemente vergrößert werden sollen.
Zum Beispiel haben wir eine Korrelation zwischen einem Wert für die Speichernutzung (ein kundenspezifisches proprietäres Softwareprogramm) und einem Neustart / Absturz festgestellt. Einer der Datenpunkte, die ich sammle, bezieht sich auf diese Speichernutzung, und ich konnte mir historische Daten ansehen, um zu zeigen, dass Geräte nach Überschreiten einer bestimmten Speichernutzung instabil werden. Für die Untergruppe der Geräte, auf denen diese Software ausgeführt wird, überprüfe ich heute diesen Wert und gebe einen Neustartbefehl aus, wenn er zu hoch ist. Bis dies entdeckt wurde, dachte ich nicht, dass das Sammeln dieser Daten von Wert ist.
Aus diesem Grund habe ich behauptet, dass die rund 100 Datenpunkte gesammelt und gespeichert werden, auch wenn der Wert fraglich ist. Im normalen Alltag untersuchen Benutzer jedoch in der Regel ein Dutzend dieser Parameter. Wenn sich ein Benutzer für ein bestimmtes geografisches Gebiet interessiert, kann er (mithilfe von Software) Diagramme oder Tabellen mit Daten für möglicherweise ein paar Dutzend Sensoren erstellen. Es ist nicht ungewöhnlich, ein 30-Tage-Diagramm mit zwei oder drei Plotlinien zu betrachten, die beispielsweise Temperatur, Luftdruck und Lichtwerte anzeigen. Wenn Sie dies tun, wird eine Abfrage ähnlich der folgenden ausgeführt:
SELECT sensor_id, location, data_timestamp, temp1, air1, light1
FROM data
WHERE data_timestamp >= '2012-02-01'
AND sensor_id IN (1, 2, 3);
(In der ursprünglichen MySQL-Version, in der jeder Sensor eine eigene Tabelle hatte, wurden drei separate Abfragen ausgegeben, die Ergebnisse wurden jedoch in Software kombiniert, um das Diagramm zu erstellen.)
Da die dataTabelle trotz aktivierter Indizes idund so viele Zeilen enthält (~ 10 Millionen), data_timestampist die Leistung erheblich schlechter als im Szenario mit mehreren Tabellen (4500 Zeilen wurden in 9 Sekunden zurückgegeben, im Gegensatz zu weniger als einer Sekunde in diesem Beispiel). Die Fähigkeit zu finden, welche Sensoren bestimmte Kriterien erfüllen, ist im Mehrtabellenschema praktisch Null und daher der Grund für den Wechsel zu einer einzelnen Tabelle.
Diese Art der Abfrage kann von mehreren Benutzern schnell hintereinander durchgeführt werden, da sie verschiedene Datengruppen auswählen und die Diagramme der einzelnen Ergebnisse vergleichen. Es kann ziemlich frustrierend sein, fast 10 Sekunden pro Grafik oder Tabelle zu warten.
Daten werden nach 90 Tagen verworfen. Es könnte archiviert werden, ist aber derzeit nicht erforderlich.
Hoffentlich können Sie anhand dieser Informationen besser erkennen, wie die Daten nach der Erfassung und Speicherung verwendet werden.