Laden...

Datenorganisation - 15 Mio Zahlen + 5 Stati ( + Synchronisation von 20+ Quellen )

Erstellt von snoop83 vor 13 Jahren Letzter Beitrag vor 13 Jahren 3.120 Views
S
snoop83 Themenstarter:in
46 Beiträge seit 2006
vor 13 Jahren
Datenorganisation - 15 Mio Zahlen + 5 Stati ( + Synchronisation von 20+ Quellen )

Hallo,

ich bin mir nicht ganz sicher, ob mein Thema hier rein gehört und weiß auch nicht so recht, wonach ich suchen könnte.

Fangen wir einfach Mal an, mein Problem ist schnell geschildert: Ich habe ca. 15 Mio Zahlen (4- bis 9-stellige, beliebige Werte). Weiterhin habe ich 5 verschiedene Stati, hier mal anonym "Status1" bis "Status5" genannt. Die Daten kommen aus einer MySQL-DB und sollen auf ein mobiles Gerät (Win CE) kopiert werden. Die Datenorganisation ist mir überlassen. Weiterhin soll eine Synchronisation in beide Richtungen möglich sein, die Geräte-Anzahl wird außerdem auf ca. 20-30 steigen.

Die eigentliche Anwendung ist folgende: Auf dem Gerät wird eine Nummer gescannt / eingegeben. Anhand dieser Nummer soll der Status herausgefunden, angezeigt sowie eventuell editiert werden. Am Ende des Tages werden alle Daten von allen Geräten in die DB synchronisiert, am nächsten Morgen von der DB auf alle Geräte synchronisiert.

Meine große Frage ist nun, wie ich diese Daten möglichst einfach auf dem Gerät organisieren, auch unter dem Aspekt, dass ich oft in beide Richtungen synchronisieren muss.

-- ( Arbeitsverzeichnis ist "\": )

Hier mein erster Ansatz:
Leere Dateien - jeder Dateiname identifiziert eine Ziffer - angenordnet nach:

\\Status1\{num1}.txt
\\Status1\{num2}.txt
...
\\Status1\{numx}.txt
\\Status2\{num1}.txt
...
\\Status5\{numn}.txt
z.B.:
\\Status1\1012.txt
\\Status1\\1179.txt
\\Status1\\124147.txt
...
\\Status1\\9941.txt
\\Status2\\11111.txt
\\Status2\\11112.txt
usw.

**:::

Nachteil: Erstellen der (15 Mio) Dateien bei DB-Export dauert ewig ; Synchronisation sehr zeitaufwendig.**

--

Zweiter Ansatz:
Für jeden Status eine Datei (welche alle zugehörigen Nummern zu diesem Status enthalten). Änderungen werden in einem anderen Verzeichnis hinterlegt:

\\in\Status1.txt
\\in\Status2.txt
...
\\in\Status5.txt
---------------------------
\\out\Status1.txt
\\out\Status2.txt
...
\\out\Status5.txt

**:::

Nachteil: Um eine Nummer zu finden, müssen im worst case alle Dateien durchsucht werden, was sehr lange dauern kann.**

--

Dritter Ansatz:
Ähnlich wie Ansatz 2, mehr Dateien, dafür bessere Vorsortierung: Die erste Ziffer einer Nummer wird als Lookup im Verzeichnis codiert:

\\in\1\Status1.txt
\\in\1\Status2.txt
..
\\in\1\Status5.txt
\\in\2\Status1.txt
\\in\9\Status5.txt
---------------------------
\\out\1\Status1.txt
\\out\1\Status2.txt
..
\\out\9\Status5.txt

**:::

Nachteil: Ich kenne die Verteilung der Nummern nicht, im worst-case beginnen sehr viele Nummern mit der gleichen Ziffer und das System geht nicht auf.**

--

Den dritten Ansatz könnte man natürlich noch verfeinern indem man anstelle der ersten Ziffer die ersten beiden oder ersten drei Ziffern in Verzeichnisse codiert.

\\in\1\0\1\Status1.txt
\\in\1\0\1\Status2.txt
..
\\in\1\1\3\Status5.txt
\\in\1\4\7\Status1.txt
...
\\in\9\9\4\Status5.txt
---------------------------
\\out\1\7\2\Status1.txt
\\out\2\0\7\Status2.txt
..
\\out\9\5\0\Status5.txt

--

Ich würde gern auf eine lokale DB auf dem Gerät verzichten (u.a. aus Zeitdruck). Was fallen euch noch für Ansätze ein, die Informationen in Dateien zu organisieren?

5.657 Beiträge seit 2006
vor 13 Jahren

Also wenn es um Performance geht, kommst du meiner Meinung nach um eine DB nicht herum. Gerade das Dateisystem ist für solche Sachen aus verschiedenen Gründen nicht besonders gut geeignet.

Weeks of programming can save you hours of planning

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo snoop83,

im Hauptspeicher ist - wenn du genug davon hast - sicher ein Dictionary <Id, Status> das günstigste. Neben dem Status muss du aber m.E. auch noch den Zeitpunkt der Änderung merken.

Die Frage ist, wieoft du überhaupt auf den Hintergrundspeicher sichern musst. Wenn das eher selten passiert, kannst du das Dictionary einfach serialisieren.

herbivore

S
324 Beiträge seit 2007
vor 13 Jahren

WLAN-Scanner + Webservice wär echt praktisch nachdenk

V
162 Beiträge seit 2010
vor 13 Jahren

Naja vielleicht schickt er auch seine Mittarbeiter mit Autos los 😃
Da wird das dann schon weniger klapen mit WLAN.

Das Leben ist schön!

2.298 Beiträge seit 2010
vor 13 Jahren

Naja aber die werden unterwegs keine 15Mio. Datensätze sammeln. - Das könnte man dann so machen dass die evtl.? 1000 Einträge serialisiert werden und sobald Netzwerkverbindung besteht die Einträge mittels eines Webservices überträgt. - So zu sagen die Einträge halt bis zur nächsten WLAN Verbindung in eine Queue stellen.

Ich mach mir da gerade nur etwas sorgen um den Speicher des Gerätes, egal welchen Weg er nutzt. - Aber sofern dauerhaft WLAN vorhanden ist würd ichs direkt übertragen und wenns mal weg ist in einer Warteschlange halten bis es wieder da ist.

Aber beides erstmal nur spekulation wie es wirklich aussieht weiß ich ja nicht.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

S
snoop83 Themenstarter:in
46 Beiträge seit 2006
vor 13 Jahren

Danke für eure Anregungen!

Also WLAN wird es keins geben, auch haben die Geräte keinerlei andere (dauerhafte) Konnektivität um irgendwelche WebServices abzufragen. Sie werden lediglich alle morgens einmal mit aktuellen Daten aus der DB versorgt und schieben Nachmittags alle gesammelten / geänderten Daten wieder zurück in das System (jeweils per Docking-Station / Cradle über USB).

@herbivore:
Das mit dem Dictionary habe ich schon versuch, das wird bereits ab 1 Mio Datensätzen kritisch. Dictionary<int, enum> frißt da ca. 60 MB, bei <string, enum> kommen wir sogar auf 80 MB ... bei 15 Mio Datensätzen wird das also nichts, gleich gar nicht auf einem mobilen Gerät.

Ist korrekt, neben dem Zeitpunkt der Datenänderung muss ich später auch wissen, auf welchem Gerät die Änderung vorgenommen wurde. Diese Information kann ich aber beim Import in die Datenbank herausfinden (Über Desktop-Tool, Gerät-Anschluss per ActiveSync).

Vielleicht hat ja noch jemand eine zündende Idee.

--

Noch weitere Hintergrundinformationen: Die 15 Mio Datensätze stehen bereits auf einem Desktop-System parat, sollen auf alle Geräte kopiert werden um dort ausgewählte Datensätze zu manipulieren. Anschließend wird 1x täglich synchronisiert (Abends von Geräte auf DB, morgens von DB auf Geräte).

2.760 Beiträge seit 2006
vor 13 Jahren

Nimm eine Embedded-Datenbank. Die Struktur der (einzigen?) Tabelle ist ja dann auch nicht weiter kompliziert:
|Wert|Status|Bearbeitet|Änderungsdatum|
Das synchonisieren kann ja ruhig ein kleines bisschen länger dauern deswegen kannst du auf jede Spalte einen Index bauen was das auffinden von geänderten Daten bzw. konkreten Datensätzen schneller macht.

Nach der Synchronisation am Morgen (Der PDA hat den selben Stand wie der Desktop) setzt du das "Bearbeitet"-Flag jedes Datensatzes auf 0 zurück und bei jeder Änderung auf dem mobilen Gerät wird es für den entsprechenden Datensatz auf 1 gesetzt und ein Änderungsdatum geschrieben. Das Änderungsdatum kannst du dann benutzen um bei Kollisionen zu prüfen ob der Datensatz auf dem PC oder auf dem PDA neuer ist.

Speicher und Performance sollten dann eigentlich kein Knackpunkt sein.

Ich würde gern auf eine lokale DB auf dem Gerät verzichten (u.a. aus Zeitdruck). Was fallen euch noch für Ansätze ein, die Informationen in Dateien zu organisieren?

Zu spät gelesen. Die DB-Implementierung solltesogar schneller gehen als die anderen Ansätze (sowohl die benötigte Zeit um eine solche Funktionalität zu programmieren als dann auch zur Laufzeit)

S
snoop83 Themenstarter:in
46 Beiträge seit 2006
vor 13 Jahren

Yep, es ist genau 1 Tabelle!

Ok, ich komm dann wohl um eine embedded-DB nicht drum rum.

Wollte es erst mit SQLite machen, aber dann habe ich noch SQL Server Compact 3.5 entdeckt und werde es jetzt damit versuchen.

Ich habe mal eben ein paar Balstungstests (1 Mio Einträge) bzgl. der Synchronisation (updates, inserts) gemacht und bin doch recht erstaunt über die (geringe) Performance. Eventuell bediene ich aber auch das PreparedSTM falsch, dazu werde ich aber einen neuen Thread starten.

309 Beiträge seit 2007
vor 13 Jahren

Hallo 😃

1.) Warum willst du immer 15 Mil. Datensätze übertragen?

Es reicht doch eigentlich aus, die Änderungen zu übertragen.

2.) Müssen am Einsatzort immer alle 15 Mil. Status bereit stehen?

Anpassen der Mobilen Daten auf den Einsatzbereich.

mfg Hajoseb

**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France

F
10.010 Beiträge seit 2004
vor 13 Jahren

@Snoop:
SQL CE Performance Insert + Select

Du hast bei Sql Compact auch an die Transaction gedacht?

S
snoop83 Themenstarter:in
46 Beiträge seit 2006
vor 13 Jahren

Ja, es müssen auf jedem Gerät alle 15 Mio Datensätze zur Verfügung stehen ... da es lediglich um das herausfinden eines Status' geht und nicht auszumachen ist, von welcher Nummer der Status benötigt wird, muss jedes Gerät "alles wissen".

@ Hajoseb:
Bei der Synchronisation von Gerät auf PC werde ich es jetzt so machen, dass nur alle geänderten Daten übertragen werden. Das passiert dann ca. 20x je Gerät am Abend, wahrscheinlich jeweils 1-5 MB.

Anschließend werden alle so gesammelten, neuen Daten in die lokale DB auf dem PC importiert.

Am Morgen erhält dann aber jedes Gerät ein komplett neues Datenpaket. Wahrscheinlich werde ich die Daten dazu 1x exportieren (MySQL -> SQL Server Compact / *.sdf-Datei) und diese Datei dann auf jedes Gerät kopieren. Wobei sich hier nach ersten Tests schon der nächste Flaschenhals anbahnt: Die Verbindung über das Cradle (ActiveSync oder per Software über rapi.dll) ist sehr langsam. Ich habe hier einen Durchsatz von ca. 250 KB/s gemessen. Bei großen Datenmengen muss ich wohl darüber nachdenken, die SD-Karten manuell per Kartenleser zu bespielen.

@ FZelle:
Per Transaction habe ich es bisher nicht versucht. Was ich aber gemacht habe ist folgendes:*Inserts/Updates per StringBuilder in Blöcken von 1000 Stück je Kommando abgesetzt *auf dem Desktop (MySQL) das Tabellenformat auf MyISAM umgestellt (vorher: InnoDB)

Bei einem Test mit 1 Mio Datensätzen ist die Performance jetzt um das 20-fache gestiegen.

309 Beiträge seit 2007
vor 13 Jahren

Am Morgen erhält dann aber jedes Gerät ein komplett neues Datenpaket.

Na, aber wenn du am Abend doch alle Status Anderungen schön sauber gesammelt hast, sollte es doch erst recht viel schneller gehen NUR diese Änderungen am Morgen an die Geräte zu verteilen ...

**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France

F
10.010 Beiträge seit 2004
vor 13 Jahren

@snoop83:
Inserts per StringBuilder?
Das bedeutet du frickelst die Parameter in den SqlString?
Das bedeutet weiterhin das kein SqlServer den Ausführungsplan cachen kann, was es auch langsamer macht.
Aber vorallem Fehleranfällig.

Wenn du sowieso die DB auf dem PC erstellst, würde ich von Updates ganz absehen, denn die machen es echt langsam ( suchen, ersetzen statt anhängen ).

Und RAPI ist so langsam, ja.