Wie speichert man in einer Datenbank am besten sehr viele Werte, die
sich nicht normalisieren lassen? Die meisten DBs machen ja bei 1000
Spalten Schluss.
Einfach nach 1000 Spalten ne 2. Tabelle anfangen ist irgendwie auch
Käse.
Konkret:
Es geht um eine Messung, bei der über 1000 (vorher bekannte) Messwerte
anfallen. Diese sollten alle zwecks nachträglicher, statistischer
Auswertungen gespeichert werden. Alle Messwerte gehören zu einer Messung
und sollten deshalb zusammenhängend gespeichert werden. Die Messung wird
vllt. ca. im 20sec-Takt durchgeführt.
jedi hand wink du brauchst keine 1000 tabellen.
und das mit dem nicht normalisieren lassen halte ich für ein gerücht.
wie sehen die daten denn (in etwa aus)?
z.B. so (Spalten):
fortlaufendeID
zeit
bereich1Io
bereich2Io
bereich3Io
bereich4Io
messwertX001
.
.
.
messwertX400
messwertY001
.
.
.
messwertY400
messwertZ001
.
.
.
messwertZ400
Falls jemand fragt, woher man so viele Daten in so kurzer Zeit bekommt:
Mit Kameras...
Also erste Idee, die mir im Kopf rumschwirrt:
MESSUNGEN:
mess_id
zeit
zB:
1; 2014-08-22,00:40:34
MESSWERTE:
mess_id
typ_id
messwert
zB:
1; 1; 28.345
1; 2; 22.874
TYPEN:
typ_id
name
zB:
1; bereich1Io
2; bereich2Io
...
876; messwertY365
muss man zwar mehr joinen, aber die Tabelle MESSWERTE ist die einzige,
die nach unten wächst. Indizes dann über die IDs.
Higher sophisticated wäre es, wenn man je nach Datentyp spezielle
Tabellen anlegt (zB. X-Y-Messwerte als Bitmap) - hängt aber auch davon
ab, was dein DBMS der Wahl so adhoc kann...
Okay, ich nehme dann mal zurück, dass die Datenbank nicht normalisierbar
ist... :D
Klingt nicht schlecht, der Lösungsvorschlag. Muss ich mal weiter
verfolgen. Danke hierfür. :)
Also ich würde die Messwerte
messwertx001 bis messwertx400
messwerty001 bis messwerty400
messwertz001 bis Messwertz400
je als Spalte in einer Memodatei (dBase)
oder als blobb-Feld speichern.
Die Datenbankstruktur könnte dann so aussehen :
messid (int/autoinkr.), zeit (String), bereich1Io(Zahl oder String),
bereich1IO(zahl/String),
bereich3Io(zahl/String),bereich4Io(zahl/string),
messwertx(Memo/blobb),messwerty(Memo/blobb),messwertz(Memo/blobb)
je nachdem, was deine DB so hergibt.
Die Messwerte natürlich mit Komma o.ä. separieren, um sie später
auch wieder gut auslesen bzw. verarbeiten zu können.
Tja Normalisierung ist schon nicht immer so einfach :-)
aber so wie T_K das beschrieben hat ist das schon richtig!
Das von Heinz beschriebene Vorgehen wäre auch wieder eine
de-normalisierte Lösung und deshalb sub-optimal. Ich programiere seit 20
Jahren hauptberuflich Datenbanken ... und immer wenn ich sowas
vorgesetzt bekomme, dreht sich mir der Magen um.
dödel schrieb:> Ich programiere seit 20> Jahren hauptberuflich Datenbanken
um das geschilderte Problem zu normalisieren reicht auch eine
"Datenbanken I"-Vorlesung
dödel schrieb:> ... und immer wenn ich sowas> vorgesetzt bekomme, dreht sich mir der Magen um.
zu recht.
Bau mir mal einer ne Abfrage, die ein Histogramm über die messwerty040
im Juni generiert. mit der von T_K normalisierten Datenbank ist das kein
Problem. Wenn die Daten in nem Blob versteckt sind - unmöglich.
wobei mir die Namen messwerty001 bis messwerty400 auch schon aufstoßen.
Hört sich auch so an, als wäre dass nicht ganz sauber.
dödel schrieb:> aber so wie T_K das beschrieben hat ist das schon richtig!
Kommt drauf an.
Kommt drauf an, ob man Kameradaten überhaupt in eine Datenbank stecken
soll.
Kommt drauf an, ob man statistische Auszuwertungen überhaupt mithilfe
einer Datenbank machen soll.
Kommt drauf an, ob immer 400 Wertetripel vorhanden sind.
Das alles könnte man erst beantowrten, wenn man den Überblick hätte,
worum es geht, aber den hat wohl nicht mal der Fragensteller.
Die Frage war nicht, ob Sie da rein gehören oder nicht. Die Frage war
WIE sie rein gehören ... und da kommt es höchstens darauf an, welches
DBMS er einsetzt. Wenn es ein RDBMS ist, dann gibt es eigentlich nur
eine korrekte Art ... und das ist die von T_K beschriebene.
Die Idee mit den BLOBs hab ich gleich verworfen. Denn dann kann ich
meine Messwerte auch gleich in einer CSV speichern.
Es sind nicht exakt 400 sondern nur etwas in der Größenordnung (exakte
Zahl ist aber im Vorhinein bekannt).
Die Daten kommen von einer Zeilenkamera (fertiges Bild ~15Megapixel) und
werden mit Bildverarbeitung extrahiert. Messwerte (zumindest X und Y)
sind Flächenschwerpunkte.
Die Werte hätte ich gern in einer Datenbank, da man
Echtzeitinformationen zu den aktuellen Messwerten anschauen kann (über
eine Homepage). Zum anderen, damit man recht unkompliziert an die Daten
gelangt. Wenn man schon mal mit mehreren hunderttausenden, teils grausam
formatierten CSV-Dateien gearbeitet hat, weiß man wovon ich spreche.
Aber ich denke der Vorschlag von T_K hört sich vernünftig an.
Fragensteller schrieb:> Aber ich denke der Vorschlag von T_K hört sich vernünftig an.
naja, wenn es wirklich Zeilen für einen Messzeitpunkt sind und immer
diese 400werte Auftreten, dann spricht nichts dagegen sie auch als eine
Zeile zu speichern.
Es gibt dafür keine allgemeine Lösung!
Wenn man z.b. 3. Messwerte hat (Strom ,Spannung, CosPhi) dann legt man
sie auch in einer Zeile mit mehre Spalten ab. Wenn es aber immer
verschiedene Messwerte gibt, oder sich die Anzahl regelmäßig ändert dann
ist es sinnvoll es als Zeilen zu speichern.
Wenn du es konstante Anzahl von Werten ist die bei jeder Messung
entstehen, da kannst du es als Spalten speichern.
da der op von flächenschwerpunkten redet, liegt die Annahme nahe, dass
er eine Art von Segmentierung macht. Demenentsprechend, wird wohl die
400 eine Art maximale Anzahl sein und die tatsächliche Anzahl von Frame
zu Frame variieren. Oder lieg ich da falsch?
Fragensteller schrieb:> Wie speichert man in einer Datenbank am besten sehr viele Werte,> die> sich nicht normalisieren lassen? Die meisten DBs machen ja bei 1000> Spalten Schluss.
Kein ernstzunehmendes RDBMS macht "bei 1000 Spalten Schluß".
Fragensteller schrieb:> Es geht um eine Messung, bei der über 1000 (vorher bekannte) Messwerte
Warum der ganze Aufwand, wenn die Werte sowieso schon bekannt sind?
asdfg
Fragensteller schrieb:> Wie speichert man in einer Datenbank am besten sehr viele Werte, die> sich nicht normalisieren lassen? Die meisten DBs machen ja bei 1000> Spalten Schluss.> Einfach nach 1000 Spalten ne 2. Tabelle anfangen ist irgendwie auch> Käse.
Wenn das Ding nur 1000 Spalten kann, dann solltest du es durch ein
richtiges RDBMS ersetzen.
> Konkret:> Es geht um eine Messung, bei der über 1000 (vorher bekannte) Messwerte> anfallen. Diese sollten alle zwecks nachträglicher, statistischer> Auswertungen gespeichert werden. Alle Messwerte gehören zu einer Messung> und sollten deshalb zusammenhängend gespeichert werden. Die Messung wird> vllt. ca. im 20sec-Takt durchgeführt.
Wie du später geschrieben hast, sind das z.B. 400 X/Y/Z-Tupel. Bei einer
PostgreSQL würde ich für X, Y und Z einfach jeweils ein Array nehmen.
Das taugt aber nur, wenn du die Werte nicht einzeln rausgreifen und
weiterverarbeiten willst, sondern immer den kompletten Satz an
Messwerten brauchst.
Hält ihn doch keiner davon ab zehn oder zwanzig Tabellen zu je 100
Spalten und derselben id zu nehmen ... am besten die Spalten so zuordnen
dass man mit nur einem Tabellenzugriff an Werte kommt die man
typischerweise zusammen benötigt. Ist sogar 3NF.
Evtl macht es sogar Sinn die Spaltenzahl auf darunterliegende
Gegebenheiten zu optimieren, zB auf eine physikalische Zeilengrösse
hinzuarbeiten die möglichst optimal Arbeitsspeicherseiten oder
Sektor/Stripegrössen des Massenspeichers ausnutzt. Da muss das DBMS
natürlich ein wenig mitspielen...
Was T_K beschreibt riecht mir nach EAV-Modell, das bringt ganz neue
Probleme mit sich. Vor allem schlechte Indizierbarkeit und astronomische
Zeilenzahlen (und wenn man nicht aufpasst astronomische Zeilenzahlen
zusammen mit Indizes niedriger Kardinalität* ... damit kriegt man zB
mysql schon bei einigen 100000 Zeilen zu einem Kolbenfresser beim
Schreiben!)
Je nachdem, was man hinterher damit machen will, könnte es auch sinnvoll
sein, hier auf eine nichtrelationale Datenbank wie Cassandra oder Monet
zu auszuweichen. Wenn am Ende vor allem aggregiert werden soll, könnte
auch ein Blick auf Hadoop/HBase interessant sein, allerdings kann es
eine Weile dauern, bis man sich in die Map/Reduce-Methode eingefunden
hat.
Ansonsten hätte ich vermutlich auch sowas wie T_K gemacht, eventuell
ohne die Typen.
@ Arc Net (arc)
>> Kein ernstzunehmendes RDBMS macht "bei 1000 Spalten Schluß".>Der war gut...
Genau ...
@Andy D
>Hält ihn doch keiner davon ab zehn oder zwanzig Tabellen zu je 100>Spalten und derselben id zu nehmen ... am besten die Spalten so zuordnen>dass man mit nur einem Tabellenzugriff an Werte kommt die man>typischerweise zusammen benötigt. Ist sogar 3NF.
So wie die Problemstellung aussieht, gibt's keine bevorzugten Meßwerte.
Also kann er sich mit Deiner Variante schon auf gewisse unperformante
Join-Orgien bei der Abfrage freuen.
>Evtl macht es sogar Sinn die Spaltenzahl auf darunterliegende>Gegebenheiten zu optimieren, zB auf eine physikalische Zeilengrösse>hinzuarbeiten die möglichst optimal Arbeitsspeicherseiten oder>Sektor/Stripegrössen des Massenspeichers ausnutzt. Da muss das DBMS>natürlich ein wenig mitspielen...
Das sind vergleichsweise marginale Optimierungen, die sofort
weggefuttert sind, wenn man joinen muß
>Was T_K beschreibt riecht mir nach EAV-Modell, das bringt ganz neue>Probleme mit sich. Vor allem schlechte Indizierbarkeit und astronomische>Zeilenzahlen (und wenn man nicht aufpasst astronomische Zeilenzahlen>zusammen mit Indizes niedriger Kardinalität* ... damit kriegt man zB>mysql schon bei einigen 100000 Zeilen zu einem Kolbenfresser beim>Schreiben!)
astronomische Zeilenzahl ja (je nachdem, was man mit astronomisch so
meint), schlechte Indizierbarkeit aber nein. Ein Index mit niedriger
Kardinalität wird ja ohnehin nur für Abfragen benutzt, die von Natur aus
schon rel. unselektiv ist. Ich sehe da nicht wirklich ein Problem ...
Den einzigen Vorteil, den ich mit Deiner Methode so sehe, ist die, daß
mehr Rows in eine Page passen, weil nur ein Teil der Spalten in jeweils
einer Tabelle lagert. Ist aber wirklich nur von Vorteil, wenn die
Abfragen immer nur eine Tabelle betreffen. Wenn dagegen die Abfragen
mehrere Tabellen überstreichen müssen, wird's Mist ...