Planung von Tabellen und Spalteneinträgen

Werbung:
Hallo,

vielen Dank erstmal noch für Eure Antworten.

Die Futterautomaten haben zwei Werte - Wasser und Futter (und es könnten weitere Größen hinzukommen).

Ich möchte mein Modell mit den 20 Futterautomaten etwas erweitern - jeder Futterautomat sendet die beiden Messwerte nicht auf einmal, sondern separat - einmal (ID, Zeitstempel, Wasser) und (ID, Zeitstempel, Futter) - aber nicht immer in der Reihenfolge Wasser-Futter sondern auch mal Futter-Wasser. ID und Zeitstempel möchte ich nun Primärschlüssel nennen.

Ich möchte nicht gleich drauf los programmieren, sondern habe mir einen Ablauf ausgedacht, den ich Euch gerne einmal vorstellen würde und ihr mir vielleicht den einen oder anderen Tipp geben könntet.

Das Problem ist, wird der Wert zum ersten mal gesendet, dann existiert der Primärschlüssel noch nicht. Es gibt den schönen Befehl "REPLACE", dieser hat aber den Nachteil, dass bei existierendem Primärschlüssel die ganze Tabellenzeile gelöscht wird. Sende ich also mit REPLACE INTO ... nacheinander die beiden Werte Wasser und Futter, dann wird beim zweiten Mal der andere Wert überschrieben, der vorher nicht gesetzt wurde.

Mein Lösungsansatz wäre folgender:

Wasswer-Wert wird gesendet:
Prüfe, ob Primärschlüssel existiert
Wenn ja, dann gehe zu Zeile Primärschlüssel und ändere den Wert Wasser.
Wenn nein, dann lege neue Zeile an mit Primärschlüssel und dem Wert Wasser.

Das heisst - ich komme nach meinem bisherigen Wissen nicht um eine Existenzprüfung drum herum.

Prüfe, ob Primärschlüssel existiert:
SELECT * FROM futtermengen WHERE AutomatID = myID AND Zeitstempel = myTimestamp

gehe zu Zeile Primärschlüssel und ändere den Wert Wasser:
UPDATE futtermengen Set Wasser = myWasser WHERE AutomatID = myID AND Zeitstempel = myTimestamp

Lege neue Zeile an:
INSERT INTO futtermengen (AutomatID, Zeitstempel, Wasser) VALUES (myID, myTimestamp, myWasser)

Jetzt fängt das Problem schon an - mache ich die Prüfung aus einem Programm heraus, dann muss ich erst abwarten, ob ein leeres Ergebnis kommt oder ob der Wert schon vorhanden ist. Gehen wir mal davon aus, dass jeder Futterautomat mit getrennten Tasks die Werte an die DB sendet, dann könnte es passieren, dass während ich auf das Ergebnis warte, parallel der zweite Wert gesendet wird. Ich könnte das natürlich softwaretechnisch unterbinden, in dem ich z.B. eine Sperrvariable setze, damit die unterschiedlichen Tasks des Futterautomaten nicht gleichzeitig senden, aber vielleicht kann ich das ja auch schon innerhalb der Datenbank erledigen.

Ich könnte als andere Alternative auch erst alle Elemente in dem Futterautomaten sammeln und dann in einem Stück senden - das wäre eine andere Alternative, aber ich möchte ja auch etwas lernen und in meinem jetzigen Modellbeispiel geht weder die Sperrvariable zur Kommunikation der Tasks noch das Sammeln der einzelnen Messwerte.

Aber vielleicht gibt es ja auch noch eine ganz andere Lösung dierekt in mySQL mit weiteren Befehlen.

Falls ihr mir ein paar Tipps geben könntet, würde ich mich sehr darüber freuen.
 
Die Futterautomaten haben zwei Werte - Wasser und Futter (und es könnten weitere Größen hinzukommen).

Dann hast schon mal ein falsches DB-Model.

Das Problem ist, wird der Wert zum ersten mal gesendet, dann existiert der Primärschlüssel noch nicht. Es gibt den schönen Befehl "REPLACE", dieser hat aber den Nachteil, dass bei existierendem Primärschlüssel die ganze Tabellenzeile gelöscht wird. Sende ich also mit REPLACE INTO ... nacheinander die beiden Werte Wasser und Futter, dann wird beim zweiten Mal der andere Wert überschrieben, der vorher nicht gesetzt wurde.

Mein Lösungsansatz wäre folgender:

Wasswer-Wert wird gesendet:
Prüfe, ob Primärschlüssel existiert
Wenn ja, dann gehe zu Zeile Primärschlüssel und ändere den Wert Wasser.
Wenn nein, dann lege neue Zeile an mit Primärschlüssel und dem Wert Wasser.

Was soll das werden - willst Du nur den letzten Stand speichern?

Du brauchst eine Tabelle mit id, timestamp, messgröße, messwert. Dann hast Du das Problem nicht.


Andreas[/quote]
 
Falls ihr mir ein paar Tipps geben könntet, würde ich mich sehr darüber freuen.

Wenn deine beiden Daten nicht atomar geliefert werden handelt es sich um zwei Datensätze. Folglich brauchst du eine Tabelle für Wasser und eine für Futter. Anschließend kannst du beide Tabellen mit einem FULL OUTER JOIN in einer View wieder zusammen führen.
 
Wenn deine beiden Daten nicht atomar geliefert werden handelt es sich um zwei Datensätze. Folglich brauchst du eine Tabelle für Wasser und eine für Futter. Anschließend kannst du beide Tabellen mit einem FULL OUTER JOIN in einer View wieder zusammen führen.

Oder so. Aber bei einem weiteren Meßwert ändert er sein Design, unschön.
 
Oder so. Aber bei einem weiteren Meßwert ändert er sein Design, unschön.
Nicht wenn die kumulierten Daten über eine VIEW genutzt werden. Letztendlich kommt es auch stark auf die Art der zusätzlichen Werte an. Im Moment haben wir ausschließlich Integer Werte. Was machst du wenn ein Textwert dazu kommt?

Darf ich Dich zitieren? "Wenn deine beiden Daten nicht atomar geliefert werden handelt es sich um zwei Datensätze."
Normalisierte Daten != Erwünschte Form
 
Vielen Dank fuer Eure vielen Antworten.

Dann hast schon mal ein falsches DB-Model.
...
Du brauchst eine Tabelle mit id, timestamp, messgröße, messwert. Dann hast Du das Problem nicht.

Ok, also müsste ich in diesem Fall davon Abstand nehmen, Wasser und Futter in einer Tabellenzeile zu haben, sondern sie werden in getrennten Zeilen gespeichert?

Dann müsste ich als Primärschlüssel aber id, timestamp und messgröße nehmen, denn sowohl die Messgröße Futter wie Wasser werden zum gleichen Zeitpunkt erfasst.

Aber jetzt fällt mir ja ein, dass ich ja das gleiche Problem schon früher hatte, wo ich alle 20 Futterautomaten in einer Zeile erfassen wollte, ihr mir davon aber abgeraten hattet und mich deshalb auf den doppelten Primärschlüssel hingewiesen habt?

Sollte man sich das bei Datenbanken dann immer so merken - dass man die Daten, die nicht in einem Rutsch kommen, immer in einer separaten Zeile erfasst?

Wenn ja, so stell ich mir das aber vielleicht auch bei großen Datenmengen etwas problematisch vor. Würde ich es so speichern:

id, timestamp, wasser, futter - dann hab ich für einen Zyklus "nur" 4 Datenfelder. Sagen wir einfach mal, so eine Variable sei 32bit breit. Also hab ich dort jetzt 128 bit.

Bei der Variante:
id, timestamp, messwert, messgröße sind es auch vier Datenfelder, aber da es zwei Messwerte sind zweimal das Datenfeld - also 256 bit. Und wenn ich dann noch einen dritten Messwert hätte, dann kommt nicht immer nur ein neues Datenfeld hinzu, sondern gleich vier.

Also müsste ich dann - um dieses Problem zu umgehen - auf der Datenerfassungseite bereits dafür sorgen, dass die Daten soweit wie möglich gebündelt an die Datenbank gesendet werden?

Oder ginge das auch - dass z.B. MySQL prüft - wie viele Daten in der Tabelle drinnen sind - sagen wir mal z.B. 1000 Futterdaten, dass dann die Daten in einer neuen Tabelle zu einer mehrspaltigen Tabelle zusammengefasst werden?
 
Sollte man sich das bei Datenbanken dann immer so merken - dass man die Daten, die nicht in einem Rutsch kommen, immer in einer separaten Zeile erfasst?
Pauschalaussagen sind schwierig. In erster Linie hängt das vom Designmodel und von den Daten selbst ab. Log-Daten wie in deinem Fall speichert man vorzugsweise einmalig als atomare Datensätze. Adressdaten zum Beispiel werden für gewöhnlich manuell erfasst und unterliegen sowieso potentiellen Änderungen.

Interessant dazu auch das Thema Normalisierung: https://duckduckgo.com/?q=normalisierung

Wenn ja, so stell ich mir das aber vielleicht auch bei großen Datenmengen etwas problematisch vor.
Von welchen Datenmengen sprechen wir pro Tag? 20, 40 oder 480 Datensätze? Die Grenzen von MySQL liegen bei 64TB pro Tabelle. Du wirst mit ~10000 Datensätzen pro Tag vermutlich Jahrzehnte brauchen um das Limit zu erreichen. Bis dahin kannst du das System wechseln oder MySQL unterstützt dann größere Tabellen.

Also müsste ich dann - um dieses Problem zu umgehen - auf der Datenerfassungseite bereits dafür sorgen, dass die Daten soweit wie möglich gebündelt an die Datenbank gesendet werden?
Wäre eine Lösung. Aber aus technischer Sicht überflüssig. Das kann die Datenbank vermutlich eh besser.

Oder ginge das auch - dass z.B. MySQL prüft - wie viele Daten in der Tabelle drinnen sind - sagen wir mal z.B. 1000 Futterdaten, dass dann die Daten in einer neuen Tabelle zu einer mehrspaltigen Tabelle zusammengefasst werden?
Die Ansicht deiner Daten hat nichts mit der physischen oder logischen Repräsentation auf der Festplatte zu tun. Wegen des Platzproblems würde ich mir wirklich keine Gedanken machen. Zumindest nicht wenn dein Datenbankserver auf einem normalen Rechner läuft.

Es kann natürlich sinnvoll sein die Daten einmal im Monat oder Jahr zusammenzufassen und auf einem externen Medium zu archivieren. Aber auch das hat erst mal nichts mit dem Datenbankdesign zu tun.

--

Ein Datenbankmodell muss optisch nicht "schön" sein. Wie du dir später von der Datenbank die Daten anzeigen lässt ist eine ganz andere Sache.

Deine Daten sind nach dem relationalen Ansatz Mengen. Ob ein Datenbankmodell schön ist entscheidet sich daher aus mathematischer Sicht.

Siehe dazu: https://duckduckgo.com/?q=relationale+algebra
 
Werbung:
Zurück
Oben