Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Messdaten in DB speichern (https://www.delphipraxis.net/57649-messdaten-db-speichern.html)

iamjoosy 24. Nov 2005 16:25

Datenbank: Access • Zugriff über: ADO

Messdaten in DB speichern
 
Hallo, folgendes Problem

ich nehme Messdaten auf, die alle 8,3ms generiert werden (120 Hz). Nun will ich diese Daten in einer DB speichern. Aus mehreren Gründen will ich diese aber nicht direkt in die DB schreiben, sondern zuerst im Speicher cachen, un nach Abschluss der Datenaufnahme physikalisch in die DB schreiben.

Bisher habe ich zwei Ansätze ausprobiert:

1) Mit einem Clientdataset und Datasetprovider und AdoDataset

2) Mit AdoDataset und BatchUpdate

jeweils mit einer AdoConnection auf eine Access DB

Das Problem ist, dass das bei beiden Ansätzen das speichern der cached data ewig dauert, was man dem späteren Nutzer nicht zumuten kann.

Nun meine Frage:

a) Ist dies ein generelles Problem bei Datenbanken (dass die inserts relativ lange brauchen)
b) Mache ich vielleicht was grundsätzliches falsch
c) Weiss jemand eine andere Lösung

Vielen Dank

joachimd 24. Nov 2005 16:46

Re: Messdaten in DB speichern
 
Zitat:

Zitat von iamjoosy
ich nehme Messdaten auf, die alle 8,3ms generiert werden (120 Hz). Nun will ich diese Daten in einer DB speichern. Aus mehreren Gründen will ich diese aber nicht direkt in die DB schreiben, sondern zuerst im Speicher cachen, un nach Abschluss der Datenaufnahme physikalisch in die DB schreiben.

soweit gut.

Zitat:

Zitat von iamjoosy
1) Mit einem Clientdataset und Datasetprovider und AdoDataset
2) Mit AdoDataset und BatchUpdate

jeweils mit einer AdoConnection auf eine Access DB

Das Problem ist, dass das bei beiden Ansätzen das speichern der cached data ewig dauert, was man dem späteren Nutzer nicht zumuten kann.

Ich würde die Werte in einer eigenen Liste verwalten und darauf einen Thread loslassen: Bis der thread irgendein Ende-Signal bekommt, soll er die Liste durchgehen, den Wert in die DB speichern und danach den Eintrag in der Liste löschen.
Vorteil: die Speicherung ist so schnell wie Applikation und DB es verkraften, der Benutzer muss am Ende des Programms nur warten, bis der Cache halt vollends abgearbeitet wurde und nicht so lange, wie eine komplette Speicherung dauert.

supermuckl 24. Nov 2005 16:47

Re: Messdaten in DB speichern
 
für so etwas würde ich ein eigenes datenbank"format" programmieren. etwa eine ringdatenbank oder sonstiges.
ansich ist meiner meinung nach access sowieso nicht für solch große datenmengen (falls sie es werden) bzw für so eine echtzeit-performance gedacht und auch in zukunft nicht mehr weiterentwickelt.

ich selbst hab solch ein system schon selber programmiert, das zwar nicht mit 120hz abtastet, jedoch 5sekündlich und dafür viele daten und aktuell ca 60 clients über netzwerk damit verbunden sind und diese schreiben in die selbst gecodete ringDB

falls ich dir beim design der DB helfen kann würde es mich freuen. auch sourcecode von meinem projekt (das zwar nicht final ist, aber stable) kann ich dir anbieten.

screeni der auswertesoftware (auch alles selbst geschrieben) gibts auf meiner page.

generell würde ich sagen, erklär mal ein wenig genauer was bzw wieviel daten du pro 8,5ms eigentlich festhalten willst und wie lange.

marabu 24. Nov 2005 17:00

Re: Messdaten in DB speichern
 
Hallo iamjoosy,

ich vermute, dass du keine kontinuierliche Messung machst, sondern nur für einen diskreten Zeitraum. Ich würde die Daten im Hauptspeicher halten, bevorzugt in einer StringList, wenn der Speicher ausreicht. In den Messpausen würde ich die Daten auf die Platte schreiben, bevorzugt im CSV-Format. Dann würde ich statt Access eher die MSDE benutzen (trotz 2GB space limit und anderen quirks) und die Daten mit dem utility bcp in die Datenbank laden. Wenn das mit minimal logging geschieht, dann sollten deine Zeitprobleme verschwinden.

Grüße vom marabu

iamjoosy 24. Nov 2005 21:01

Re: Messdaten in DB speichern
 
Vielen Dank ertsmal für eure Antworten,

hier das ganze noch etwas genauer:

Das Messsystem sampelt mit 120Hz, dabei entstehen pro datensample ca. 100 Bytes daten. Die Datenaufzeichnung ist variabel in der Länge, kann aber bis 1h oder sogar noch mehr gehen. Kurz gerechnet:

120*60*60*100Bytes = 43,2 MB Daten die da anfallen.

Nun, ich könnte die Daten ja auch kontinuierlich in die DB schreiben, aber dies will ich tunlichst vermeiden, da paralell zu der Datenaufzeichnung auch noch ein Screenrecording läuft, bei dem es wichtig ist, dass es möglichst schnellen Zugriff auf die Festplatte hat (das ist da nämlich der Flaschenhals).

Bisher habe ich das ganze über ein clientDataset mit anschließend lokaler Speicherung gelöst, das funktioniert soweit auch ganz gut. Nur dass ich jetzt aus Gründen der einfacheren Handhabung die Daten in einer SQL basierten Datenbank gerne hätte, da man damit das Datenhandling gegenüber in mehereren lokalen CDS Dateien erheblich vereinfachen kann (z.b. brauche ich zur Auswertung der daten nicht immer die ganzen Daten - beim CDS kann ich aber nur den ganzen Satz Daten einlesen - was a) Ressourcenverschwendung und b) gegenenfalls gar nicht mehr in den Hauptspeicher passt.

@Joachim

Deine Lösung wäre, sozusagen die Daten "im Hintergrund" abzuspeichern - das löst mein Problem nicht wirklich, da der Benutzer trotzdem warten müsste bis die daten geschrieben sind um dann eine neue Aufzeichnung starten zu können.

@supermuckl

Wie gross kann denn eine Access DB sein? Bin da leider kein Experte
Ich dachte, da könnte ich zum Schluss schon 1 oder 2 GB reinpacken - geht da Access in die Knie?
Eine eigene DB-Lösung möchte ich eigentlich gerne vermeiden, aus oben genannten SQL gründen - mit SQL wird die Auswertung schon fast zum Kinderspiel, ansonsten muss man eine Menge Code programmieren, der a)Fehleranfällig ist und b) für mich viel schlimmer, meistens viel schwerer erweiterbar, als mit einer selbstgestrickten DB - letzteres ist auch der Grund warum ich von CDS auf eine "richtige" DB das Projekt umschreiben (eigentlich komplett neuschreiben) will.

@marabu

wie schon oben vorgerechnet, sollte der Platz im Speicher ausreichen - bisher sind die Daten im CDS ja auch im Speicher gelandet - das schöne hier war, dass das speichern der Daten auf Festplatte doch erstaunlich flott ging - ich werde wahrscheinlich mal morgen einen Test machen und diesen dann hier berichten: Daten vom CDS direkt geschrieben vs. CDS über Provider über ADO in Access DB vs. ADO mit cached updates direkt als File geschrieben vs. ADO cached Updates in Access DB mit BatchUpdates.

über MSDE habe ich auch schon nachgedacht, aber vor allem in Zusammenhang mit Delphi nicht viel darüber gefunden - wie spricht man die MSDE denn von Delphi aus an? Gibt es da auch einen Treiber, wie die Jet Engine für Access?

marabu 24. Nov 2005 21:45

Re: Messdaten in DB speichern
 
Zitat:

Zitat von iamjoosy
wie spricht man die MSDE denn von Delphi aus an? Gibt es da auch einen Treiber, wie die Jet Engine für Access?

Auch die Microsoft Desktop Engine wird über ADO angesprochen. Du verwendest einfach den OLE DB Provider für den SQL Server. Wegen deiner Erwähnung von MS Access habe ich eine gewisse Affinität zu MS Produkten unterstellt und deshalb auf eine vorteilhafte Alternative (MSDE) zu Access verweisen wollen. Damit wollte ich keinesfalls andere bewährte Produkte kategorisch ausschließen, wie den ADS, MySQL oder Firebird, um nur einige wenige zu nennen.

marabu

iamjoosy 24. Nov 2005 22:00

Re: Messdaten in DB speichern
 
@marabu
nein, was MS oder sonstige Produkte angeht bin ich völlig emotionslos - Access habe ich ausprobiert, weil ich da bisher nichts installieren musste.
Über die verschidene DBs gibts ja auch sehr unterschiedliche Meinungen, aber vielleicht kann mir jemand zu einer zukunftsfähigen lokalen DB raten - ich denke mit Paradox und BDE sollte man besser nicht mehr anfangen, oder?

supermuckl 24. Nov 2005 22:31

Re: Messdaten in DB speichern
 
wie gesagt ich würde mir an deiner stelle überlegen das selbst in die hand zu nehmen. ich weis jetzt nicht in wieweit du da querys bauen musst.. ich dachte halt eher an das was ich da gebaut hatte - ein messdaten erfassungs und auswertesystem, das messdaten in kennlinienform dann darstellen kann.. auch mit indexfile über datetime - aber das ist auch das einzige was ich an "querys" hab.
wozu sollte ich da auch mehr machen können als ein datumzeit bereich aus der DB abzufragen. was deine anwendung betrifft hab ich halt immernoch keinen schimmer was du da aufzeichnest und was du da an querys bauen willst
ich zeichne cpu auslastung, ram auslastung, netzwerkkarten up/download und auslagerungsdatei-auslastung auf und stell sie dar.

Jelly 24. Nov 2005 22:52

Re: Messdaten in DB speichern
 
Also jetzt mal so rein aus dem Bauch raus, denk ich nicht das MSSQL (bzw. MSDE) Probleme kriegt, 45MB Daten in einer Stunde zu speichern. Du musst ja nicht gleich einen Index auf jede Spalte legen. Dadurch dauert die Auswertung dann vielleicht ein paar Sekunden länger. Ich hab keine Ahnung wie rechenintensiv deine Messung selbst ist. 120 Hz kriegt man ja noch fast mit blossem Auge mit :-) Ist zwar ein bischen übertrieben. Eventuell kannst du auch auf einen zweiten Rechner ausweichen, der als reiner SQL Server dient. Dazu kannst du dann jedes Datenpaket im 120 Hz Abstand in einem eigenem Thread zum Server schicken einem schlichtem SQL Befehl à la "insert into..." und nicht etwa über die Delphi Komponten mittels Insert...Post. Also es wär ein Versuch wert.

Ein Messung dauert eine Stunden, bei 120 Hz sind das ja rund 500.000 Records. Probiers doch einfach mal so aus, 500.000 Records in einer Tabelle unterzubringen, und stoppe die Zeit. Du musst ja nicht gleich jede Messung in ein und diesselbe Tabelle knallen. Für die Auswertung gibts da bestimmt noch andere Möglichkeiten.

Aber vielleicht schilderst du uns mal genauer, wie aufwendig die Messung und die Auswertung sind.

iamjoosy 24. Nov 2005 23:08

Re: Messdaten in DB speichern
 
@jelly
45MB Daten in einer Stunde schafft auch Access, das ist nicht das Problem. Ich möchte aber vermeiden, dass während der Datenaufzeichnung auf die HD zugegriffen wird, da wie oben beschrieben (in manchen Fällen) auch noch ein Screenrecording mit paralell läuft.

iamjoosy 24. Nov 2005 23:15

Re: Messdaten in DB speichern
 
Liste der Anhänge anzeigen (Anzahl: 1)
huups, Nachricht geschrieben und nicht abgeschickt, also hier nochmal:

@supermuckl & jelly

die Daten kommen von einem Eyetracker - ein sehr teures Gerät, mit dem man messen kann wo Menschen auf einem Bildschirm (oder sonstwo) hinschauen. Das ganze kann man z.B. für usability tests verwenden.
Da man da aber mit meheren Personen arbeitet ist die Verwaltung in einer richtigen DB mit Querys schon sehr wünschenswert.

Also nochmal: Mein problem ist, wie ich die daten aus dem Hauptspeicher möglichst schnell in eine lokale DB bekomme, damit ich später schön mit Querys etc damit arbeiten und meine Daten auswerten kann.

Eine, der Auswertungen habe ich mal hier angehängt.

joachimd 25. Nov 2005 08:08

Re: Messdaten in DB speichern
 
Zitat:

Zitat von iamjoosy
@Joachim

Deine Lösung wäre, sozusagen die Daten "im Hintergrund" abzuspeichern - das löst mein Problem nicht wirklich, da der Benutzer trotzdem warten müsste bis die daten geschrieben sind um dann eine neue Aufzeichnung starten zu können.

Warum? Du kannst doch eine neue Aufzeichnung in einem neuen Thread starten (neue Queue), gleichzeitig einen neuen Thread starten, der die Daten abspeichert (von der anderen Queue heraus) und Dein Benutzer kann richtig schön weiterarbeiten. Wenn Du dann nicht in eine Datei, sondern eine DB speicherst, so sollte das auch keine Probleme mit Deinem anderen Programm/Thread machen.

iamjoosy 25. Nov 2005 08:14

Re: Messdaten in DB speichern
 
Das würde aber mein Problem nicht lösen, dass während einer Datenaufzeichnung keine Festplattenzugriffe stattfinden sollen - siehe Erklärung oben.

joachimd 25. Nov 2005 08:19

Re: Messdaten in DB speichern
 
Zitat:

Zitat von iamjoosy
Das würde aber mein Problem nicht lösen, dass während einer Datenaufzeichnung keine Festplattenzugriffe stattfinden sollen - siehe Erklärung oben.

Doch. Wenn Du ein DBMS (sorry, vielleicht genauer: Client/Server DBMS) einsetzt, hast Du absolut keine Plattenzugriffe, sondern nur auf das Netzwerk. Auf der anderen Seite: Wie verhinderst Du, dass Windows nicht auf die Platte schreibt? Das geht m.W. überhaupt nicht (Stichwort Swapping).

trifid 25. Nov 2005 08:27

Re: Messdaten in DB speichern
 
Hallo,

ich würde folgenden Varinate vorschlagen
verwende ein TObjectList - das Item enthält die Messdatenstruktur (Datum, Zeit, Messnummer, Messwert1, Messwert2, etc.)
(das geht schnell und man kann es auch threadsicher programmieren)
(oder doch eine TStringListe - da musst du mal Zeitmessungen machen)
Nach dem Mess-Ende diese Liste in einen File ablegen
Anschließend die Datei über einem "bulk copy" in die MSDE reinladen mit dem Tool bcp.exe
(das geht auch wieder fix, wenn die Dateistruktur gleich der Tabellenstruktur ist)

Wenn du Multithreading verwendest möchtest , könntest du beides gleichzeitig anwenden und "nonstop" Messreihen fahren
1ter Thread nimmt Messung auf und legt die Daten in die TObjectList/TStringList
2ter Thread verwaltet die Messreihen und erzeugt in 1000er oder 10000er die Datei
3ter Thread verwaltet das Löschen der Objectlist bereits übertragener Daten (dafür brauchst du ein Löschkennzeichen im Item)
4ter Thread führt den "bulk copy" durch

Ich würde mich nicht mit ADO oder der MSAccess abgeben (weil die Schnittstelle zu langsam ist), eher würde ich
eine DBase (.dbf) Datei verwenden wo gleich die Messdaten reingeschrieben werden
(weil dies einfach mit DBase schneller geht)
( nicht über die BDE ((da ist auch zuviel zwischen drin)) eher http://sourceforge.net/projects/tdbf)
(nebenbei, viele Industrieschnittstellen verwenden DBase als Datenbankaustauschformat, weil es einfach, schnell und netzwerktauglich ist)
wenn's mit "ADS Advantage Local Server" geht, soll es genau so gut sein (wichtig ist, das die Abtastung von 8ms erhalten bleibt)
Anschließend die Daten in einen SQL-Server deiner Wahl importieren - für eine komfortable und schnelle Auswertungsmöglichkeit

Einen Ringbuffer wie hier vorgeschlagen würde ich nicht empfehlen, da du nie weißt ob die Daten überrollt werden
Außerdem ist die Verwaltung von einem Ringbuffer auch nicht ganz ohne - wenn gleichzeitig 2 Prozesse lesend oder schreiben darauf zugreifen
Eine eigene Datenbank macht wenig sinn, weil es genügend Alternativen für dein Problem gibt


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz