# Grosse Menge an Daten in eine Datenbank



## headnut (19. Nov 2012)

Guten Abend

Ich müsste 240 double werte in eine Datenbank schreiben.

Nun meine Frage wie ich das am besten bewerkstellige, weil so grosse Geschichten musste ich noch nie machen.

Edit: Die Daten sind eine einer Arraylist

Vielen Dank schon mal für die Anregungen


----------



## Michael... (19. Nov 2012)

Viel ist ja immer relativ (und subjektiv), wobei ich 240 double Werte nicht als solches bezeichnen würde. Sind das 240 Datensätze oder besteht ein Datensatz aus 240 Werten?
Wenn's nicht sonderlich zeitkritisch ist würde ich per Schleife über die ArrayList die Daten in die Datenbank schieben. Zusätzlich gibt es noch die Möglichkeit, statt jedes Statement einzeln diese zu sammeln in einem Batch auszuführen.


----------



## headnut (19. Nov 2012)

Joa das ist klar 

Nein es sind 240 einzelne Werte... 

Ich habe gehoft das ich mir den Schreibaufwand verringern könnte weil es vielleicht eine bessere Lösung gibt als den Befehl ganz auszuschreien...

Aber in dem Fall nicht, und nein es ist überhaupt nicht Zeitkritisch...


----------



## Camino (19. Nov 2012)

headnut hat gesagt.:


> Nein es sind 240 einzelne Werte...



240 Werte pro Datensatz? Oder insgesamt 240 Werte? Kannst/möchtest du mal kurz erklären, was du da in der Datenbank abspeicherst? Vielleicht gibt es ja eine andere, bessere Möglichkeit, z.B. in dem man die Datenbank anders strukturiert.


----------



## Michael... (19. Nov 2012)

headnut hat gesagt.:


> Ich habe gehoft das ich mir den Schreibaufwand verringern könnte weil es vielleicht eine bessere Lösung gibt als den Befehl ganz auszuschreien...


Welchen Schreibaufwand? Im simpelsten Fall ist es doch nur eine Zeile (für den Schleifenkopf) mehr. Will man den Batchmechanismus nutzen kommen halt noch ein paar Zeilen dazu.


----------



## headnut (19. Nov 2012)

Jap mach ich Entschuldigung.

Ich habe 40 Messwerte, und jede Messung hat 6 double Werte ( 40 x 6 = 240 ). Die Messung erfolgt jede Stunde einmal, ist von daher überhaupt nicht zeitkritisch.

Desweiteren kommen, nach aktuellem Stand, Das gleiche noch boolisch dazu, nämlich die Auswertung.

Das macht somit 480 Werte


----------



## Camino (19. Nov 2012)

Hmm, und wenn du das auf 2 Tabellen aufteilst? Eine Tabelle hat die Messungen als Datensätze mit den 6 double-Werten, ein Feld für einen Fremdschlüssel (40 Messwerte in anderer Tabelle), sowie 6 boolean-Felder für die Auswertung. Wäre vielleicht ein bisschen übersichtlicher.


----------



## headnut (19. Nov 2012)

Ich gebe dir Recht, es wäre übersichtlicher.

nur wie generiere ich einen Automatischen und einmaligen schlüssel? über einen TIMESTAMP vielleicht?

Weil später sollten daraus Auswertungen erfolgen, und da brauch ich eindeutige Schlüssel


----------



## Fab1 (19. Nov 2012)

In der Regel machen das DBMS wie zum Beispiel MySQL von alleine. Einfach ein Feld als 
Primärschlüsselfeld und mit AUTO_INCREMENT Kennzeichnen und sobald ein Datensatz eingefügt wird, wird um eins hochgezählt.

Somit hat jeder Datensatz seine einzigartige ID.


----------



## Camino (19. Nov 2012)

Welchen Schlüssel meinst du denn jetzt? Den Fremdschlüssel der 40 Messwerte? Automatische Schlüssel sollte eigentlich das Datenbanksystem erzeugen können.

Die Frage ist vielleicht noch, ob du immer neue Messungen einträgst, oder ob die jeweiligen immer überschrieben werden, wenn es neue Messwerte gibt.

Überlegen müsste man evtl. auch noch, wie die Daten in die Datenbank eingetragen werden, also in welcher Form sie vorliegen.


----------



## headnut (19. Nov 2012)

Ja stimmt. Denn wenn man einen Datensatz löscht, wird die id trotzdem weitergezählt


----------



## Camino (19. Nov 2012)

headnut hat gesagt.:


> Ja stimmt. Denn wenn man einen Datensatz löscht, wird die id trotzdem weitergezählt



Ist ja auch irgendwie logisch. Weil jeder Datensatz seine eindeutige Kennung (ID) haben sollte. Wenn nicht, also wenn die gleich ID dann noch einmal vergeben werden würde und evtl. diese ID in einer anderen Tabelle als Fremdschlüssel eingetragen wäre, dann würde ja die Datenzuordnung nicht mehr stimmen. Wenn du die ID beibehalten möchtest, kannst du ja auch mit UPDATE den Datensatz ändern.

Es gibt übrigens auch die Möglichkeit bei Datenbanksystemen, darauf zu reagieren, wenn ein Datensatz gelöscht wird, und dessen ID noch in einer anderen Tabelle als Fremdschlüssel eingetragen ist.


----------



## Tomate_Salat (19. Nov 2012)

Camino hat gesagt.:


> Es gibt übrigens auch die Möglichkeit bei Datenbanksystemen, darauf zu reagieren, wenn ein Datensatz gelöscht wird, und dessen ID noch in einer anderen Tabelle als Fremdschlüssel eingetragen ist.



Stichwort: [c]Foreign Key[/c] mit kaskadierendem löschen.


----------



## Camino (19. Nov 2012)

Tomate_Salat hat gesagt.:


> Stichwort: [c]Foreign Key[/c] mit kaskadierendem löschen.



Ja, z.B. bei PostgreSQL kann man auch das Löschen verhindern, den anderen Datensatz ebenfalls löschen (kaskadierend), den Eintrag beim Fremdschlüssel auf NULL oder auf einen DEFAULT-Wert setzen.


----------



## headnut (20. Nov 2012)

Vielen Dank schobmal für die Vorschläge.

Ich muss am morgen zu einem Kunden und werde
mir das heute Nachmittag zu gemüte führen.

Gruss


----------



## tuxedo (20. Nov 2012)

Sehe da gar kein Problem 6 Double-Werte + 6 Bollean-Werte in einer Tabelle zu speichern. Die Boolean-Werte würde ich nur dann in eine separate Tabelle auslagern, wenn diese thematisch nicht direkt etwas mit der Messung zu tun haben.

Zum Vergleich:

Ich schreibe im Minutentakt folgende Messwerte unserer Erdwärmeheizungsanlage in einer Tabelle:

* ID
* Timestamp
* 15x tinyint(1) -> Zustand diverser Pumpen und Ventile: An/Aus
* 21x double -> Temperaturen und andere Messgrößen
* 6x int(11) -> Temperaturen und andere Messgrößen
* und nochmal 4x double -> Temperaturen und andere Messgrößen

Mittlerweile habe ich über 570.000 Messdatensätze dieser Art in der MySQL Datenbank, welche unter Debian auf einem SheevaPlug ? Wikipedia Computer läuft. Gefüttert wird die DB mit einer Java-Konsolen-Anwendung (OpenJDK für ARMv5) die per CronJob 1x/Minute gestartet wird.

Analog zu deiner "Rechnung" sind das 48 Werte pro Minute, oder jetzt insgesamt 2,7Mio Werte in der DB.

Bisher gibt's da weder Probleme mit der Kapazität (die Daten brauchen nur etwa 141MB), noch mit der Performance von Abfragen (auch wenn sie etwas komplizierter sind) oder Inserts.


----------



## headnut (20. Nov 2012)

Das würde die ganze Sache erleichtern. 

Die länge schreckt irgendwie ab, keine Ahnung.

Aber du hast Recht, da ich nur jede Stunde einmal speichern werde, maximal vielleicht 5 mal ist es wirklich nur die Länge der Abfrage die abschreckt.

Ich denke ich werde eine Abfrage machen


----------



## tuxedo (20. Nov 2012)

Mit "Abfrage" meinst du das SQL-Statement für den INSERT?
Ja, das ist bei mir etwas lang. Aber a) stört es mich nicht, b) wieso sollte ich das künstlich auf mehrere Tabellen aufsplitten, wenn doch alle Werte thematisch direkt zusammengehören und c) es so keine Speicher- und Performancenachteile bringt?

Bei dir bin ich mir bzgl. der Splittung aber gerade nicht mehr sicher. Du schreibst du hast 6 Messwerte, und dazu nochmal 6 Boolean-Werte, welche die "Auswertung" der Messwerte darstellen?

Kannst du das etwas genauer ausführen? So spontan würde ich jetzt sagen:

Zwei Tabellen: Eine mit den Messwerten, und eine mit der Auswertung:


```
Messwerte
------------------------
id: int
zeitstempel: timestamp ???
messwert1: double
messwert2: double
messwert3: double
messwert4: double
messwert5: double
messwert6: double

Auswertung
------------------------
id: int
zeitstempel: timestamp ???
id_messwert: int
auswertung1: boolean
auswertung2: boolean
auswertung3: boolean
auswertung4: boolean
auswertung5: boolean
auswertung6: boolean
```

Tabelle "Messwerte" ist denke ich klar. Evtl. noch ein Zeitstempel, falls der gebraucht wird. Eine ID sollte man so oder so haben.

Auswertung: Ebenfalls wieder eine ID, und auch wieder, falls benötigt, ein Zeitstempel. Mit "id_messwert" bekommst du die Verknüpfung zum jeweiligen Messwert und auswertung 1-6 ist auch wieder klar.

Wie entsteht denn die Auswertung? Passiert die in einem Atemzug mit der Messung, oder läuft die separat ab?

- Alex


----------



## Camino (20. Nov 2012)

tuxedo hat gesagt.:


> Bei dir bin ich mir bzgl. der Splittung aber gerade nicht mehr sicher. Du schreibst du hast 6 Messwerte, und dazu nochmal 6 Boolean-Werte, welche die "Auswertung" der Messwerte darstellen?



Am Anfang waren es 240 double-Werte, die in die Datenbank geschrieben werden sollten. Deshalb kam der Vorschlag, dies in 2 Tabellen zu splitten und pro Datensatz 6 double-Werte für die Messungen, 6 boolean-Werte für die Auswertung und einen Fremdschlüssel auf die zweite Tabelle, welche die einzelnen Messwerte darstellt. So weit waren wir also schon einmal.



> Ich habe 40 Messwerte, und jede Messung hat 6 double Werte ( 40 x 6 = 240 ). Die Messung erfolgt jede Stunde einmal, ist von daher überhaupt nicht zeitkritisch.
> 
> Desweiteren kommen, nach aktuellem Stand, Das gleiche noch boolisch dazu, nämlich die Auswertung.
> 
> Das macht somit 480 Werte


----------



## tuxedo (20. Nov 2012)

Jepp, soweit waren wir schonmal. Allerdings hat keiner Hinterfragt wie es zu den Auswertungen kommt. Wenn diese Auswertung separat vom INSERT der Messwerte abläuft, dann macht eine zweite Tabelle Sinn. Wenn das aber in einem Abwasch passiert, dann kann man das getrost in eine Tabelle schreiben.

Kommt halt stark drauf an was diese Auswertung ist, und woher sie kommt.

- Alex


----------



## Camino (20. Nov 2012)

tuxedo hat gesagt.:


> Jepp, soweit waren wir schonmal. Allerdings hat keiner Hinterfragt wie es zu den Auswertungen kommt. Wenn diese Auswertung separat vom INSERT der Messwerte abläuft, dann macht eine zweite Tabelle Sinn. Wenn das aber in einem Abwasch passiert, dann kann man das getrost in eine Tabelle schreiben.



In 1 Tabelle mit 240 Feldern (double) und nochmal so viele boolean-Felder für die Auswertung?



> Kommt halt stark drauf an was diese Auswertung ist, und woher sie kommt.



Doch , wurde schon mal etwas nach mehr Infos nachgefragt...



> Die Frage ist vielleicht noch, ob du immer neue Messungen einträgst, oder ob die jeweiligen immer überschrieben werden, wenn es neue Messwerte gibt.
> 
> Überlegen müsste man evtl. auch noch, wie die Daten in die Datenbank eingetragen werden, also in welcher Form sie vorliegen.


----------



## Camino (20. Nov 2012)

> Ich habe 40 Messwerte, und jede Messung hat 6 double Werte ( 40 x 6 = 240 ). Die Messung erfolgt jede Stunde einmal, ist von daher überhaupt nicht zeitkritisch.
> 
> Desweiteren kommen, nach aktuellem Stand, Das gleiche noch boolisch dazu, nämlich die Auswertung.
> 
> Das macht somit 480 Werte



Man weiss halt nicht genau, was diese 40 Messwerte sind. Aber die werden evtl. ja auch eigene Bezeichnungen oder Eigenschaften haben. Deshalb würde ich für diese 40 Messwerte eine eigene Tabelle anlegen und dann deren ID (Primärschlüssel) bei der anderen Tabelle mit den Messungen und Auswertungen dort als Fremdschlüssel eintragen. Somit ist auch die Tabelle mit den 40 Messwerten besser änderbar. Stell dir vor, du schreibst in 1 Tabelle die 240 double-Felder und dann ändert sich was bei den Messwerten, also es kommen welche hinzu oder fallen welche weg. Dann musst du jedesmal die Tabellenstruktur ändern.


----------



## tuxedo (20. Nov 2012)

Camino hat gesagt.:


> In 1 Tabelle mit 240 Feldern (double) und nochmal so viele boolean-Felder für die Auswertung?



Und? Sofern man das Statement nicht jedesmal von Hand baut, sondern über ein Programm ein Prepared Statement mit Werten füllt: Wo ist das Problem? Die DB juckt das nicht wirklich. Gut, ist vielleicht etwas außergewöhnlich. Aber gibt's einen (technischen?) Grund das nicht zu tun?

[EDIT]Wenn ich meine Messung in mehrere Tabellen aufgespalten hätte, dann müsste ich mir bei den Abfragen teilweise ein Bein ausreißen um die Statements zu formulieren.[/EDIT]




> Stell dir vor, du schreibst in 1 Tabelle die 240 double-Felder und dann ändert sich was bei den Messwerten, also es kommen welche hinzu oder fallen welche weg. Dann musst du jedesmal die Tabellenstruktur ändern.



Das muss man abwägen. Meine Struktur hat sich mit der Zeit auch geändert. Ist gewachsen. Gut, hab ich halt alte Datensätze die in diesen neuen Feldern keine Werte drin haben. Stört mich nicht. Würde schon mehr stören wenn Felder wegfallen, aber alte Messungen die Werte noch behalten sollen. Finde ich aber eher ungewöhnlich. Aber wie gesagt: Muss man abwägen




> Doch , wurde schon mal etwas nach mehr Infos nachgefragt...



Okay, hab ich übersehen. Aber gab's eine Antwort? AFAIK nicht. Also schadet das erneute Nachfragen nicht.


----------



## Camino (20. Nov 2012)

Es hat schon einen Grund, dass es Primär- und Fremdschlüssel gibt und dass man versucht, dass möglichst zu strukturieren und nicht alles in eine Tabelle kloppt. (Normalisierung)



tuxedo hat gesagt.:


> Okay, hab ich übersehen. Aber gab's eine Antwort? AFAIK nicht. Also schadet das erneute Nachfragen nicht.



Stimmt. Na ja, die Antwort bezüglich den 40 Messwerten gab es noch nicht, also wie diese strukturiert sind. Und wie die Daten in die Datenbank kommen.


----------



## Camino (20. Nov 2012)

tuxedo hat gesagt.:


> [EDIT]Wenn ich meine Messung in mehrere Tabellen aufgespalten hätte, dann müsste ich mir bei den Abfragen teilweise ein Bein ausreißen um die Statements zu formulieren.[/EDIT]



Die Statements wären doch bei der gegebenen Struktur (40 Messwerte mit jeweils 6 Messungen und 6 Auswertungen) immer die gleichen, nur der eine Wert (ID des Messwerts) ändert sich. Müsste doch dann mit einer Schleife prima zu durchlaufen sein.


----------



## ARadauer (20. Nov 2012)

ach wie schön ich muss gerade 240.000.000 datensätze in eine datenbank schreiben :-(


----------



## Camino (20. Nov 2012)

ARadauer hat gesagt.:


> ach wie schön ich muss gerade 240.000.000 datensätze in eine datenbank schreiben :-(



Per Hand...?


----------



## tuxedo (20. Nov 2012)

> Es hat schon einen Grund, dass es Primär- und Fremdschlüssel gibt und dass man versucht, dass möglichst zu strukturieren und nicht alles in eine Tabelle kloppt. (Normalisierung)



Ist mir bekannt, seh ich auch ein. Aber es gibt eben seltene Fälle wo es unnötig oder "über-designed" wäre das ganze aufzusplitten.



> Die Statements wären doch bei der gegebenen Struktur (40 Messwerte mit jeweils 6 Messungen und 6 Auswertungen) immer die gleichen, nur der eine Wert (ID des Messwerts) ändert sich. Müsste doch dann mit einer Schleife prima zu durchlaufen sein.



Bei einfachen Abfragen wie "Gib mir alle Messdaten deren Auswertung passend zu Zeitstempel XYZ" .. Ja. Aber bei komplexeren Dingen wird es mit mehreren Tabellen auch schnell komplexer als mit einer einzelnen.


----------



## Camino (20. Nov 2012)

tuxedo hat gesagt.:


> Bei einfachen Abfragen wie "Gib mir alle Messdaten deren Auswertung passend zu Zeitstempel XYZ" .. Ja. Aber bei komplexeren Dingen wird es mit mehreren Tabellen auch schnell komplexer als mit einer einzelnen.



Es wären ja auch nur 2 Tabellen:

Messwerte
----------
id
bezeichnung


Messungen
----------
6 double-Felder (Messungnen)
6 boolean-Felder (Auswertungen)
1 int-Feld (id, Fremdschlüssel aus Messwerte)
evtl. einen Timestamp für den Zeitpunkt der Messung


----------



## headnut (21. Nov 2012)

Oha da gibt es je fast eine grundsatzdiskussion...

Ich versuche nun zu erklären wie es zu den werten kommt.

Es werden 40Teile miteinander gepresst, jedes Teil ist rund. Jedes Teil wird an 6 orten gemessen. 

Jeder dieser 6 Werte muss separat ausgewertet werden, damit wenn ein messer nicht stimmt man dies spezifisch nach justieren kann.

Somit ergibt das 40 teile a 6 Messwerte und 6 Auswertungen. 

Alles möchte ich in die DB speichern damit man in 2 Jahren Auswertungen machen kann. Die DB wird mit 480 Einträgen pro zeile doch recht unübersichtlich oder sehe ich dies falsch?

Das mit dem Primärschlüssel und Fremdschlüssel leuchtet mir am ehsten ein, und ich denke dass ich diese Architektur wählen werde. Ich mache mir ansonsten Sorgen mit der Grösse mit der Zeit... Wir sprechen über 5 solchen Messungen pro Stunde.


----------



## bananajoe (25. Nov 2012)

tuxedo hat gesagt.:


> Und? Sofern man das Statement nicht jedesmal von Hand baut, sondern über ein Programm ein Prepared Statement mit Werten füllt: Wo ist das Problem? Die DB juckt das nicht wirklich. Gut, ist vielleicht etwas außergewöhnlich. Aber gibt's einen (technischen?) Grund das nicht zu tun?



Die Frage ist eher, gibt es Gründe die Daten derart abzulegen? Falls es keine gibt, würde ich davon absehen, da man damit mehr Nachteile als Vorteile hat.

Von den Beschreibung würde ich ganz klar die Daten in zwei Tabellen ablegen. Zu jeder Messung in einer Tabelle gehört zum Beispiel eine Beschreibung und andere Attribute, die in einer Tabelle abgelegt werden sollten, um Redundanz zu vermeiden. Die Beziehung Beschreibung -> Messung ist somit eine 1 -> n. Siehe auch obiger Post von Camino. In einem prepared statement lässt sich gut joinen!

Die Grösse der DB hängt nicht mal von der Anzahl Datensätze ab, sondern wie gross die Tablespaces werden können. Diese Grösse hängt nicht nur von mySQL sondern insbesondere vom Betriebssystem ab! Bei mySQL ist die Grösse derart gross genug, dass meist das Betriebssystem eine Limite darstellt. Finde das heraus und dividiere diese Grösse mit der Grösse für einen Datensatz und so hast Du überschlagsmässig die maximale Anzahl Datensätze.


----------



## OlliL (3. Dez 2012)

Mein Lösungsvorschlag:

Tabelle "*messung*"
id
(bezeichnung) fragwürdig ob sinnvoll - hängt stark von der Verwendung ab
datum

Tabelle "*messtyp*"
id
bezeichnung

Tabelle "*messwert*"
id
id_messung
id_messtyp
wert
ergebnis


Ggfl. kann man das ganze auch noch eine weitere Ebene abstrahieren und "ergebnis" noch in eine eigene Struktur packen.
Neben der Normalisierung was schon allein der Grund für eine entsprechende Struktur sein sollte:
- Du bekommst eine schnelle Möglichkeit rauszufinden welche Messungen in welchem Zeitraum liegen (kleine Tabelle messung)
- Wenn du nach zwei Jahren 2 neue Sensoren dazuschalten willst, wird das hiermit sehr simpel.


----------



## bananajoe (3. Dez 2012)

Ich muss mich langsam meinen Vorrednern anschliessen: Die Überschrift ist irreführend. Beruflich arbeite ich auf einer DB mit 300 Mio Datensätze pro Tabelle. Ok, die DB läuft auf AIX und im Cluster um die 100 Knoten. Aber selbst auf dem eigenen PC ist die Antwortzeit einer DB mit einigen 1000 Datensätzen immer noch gut. Insofern bleibt die Frage des Designs um Datenredundanz und Inkonsistenzen zu vermeiden.


----------

