Hallo!
Und ich habe die Synchronisation zu einem BEstehenden Single-Db-System dazu entwickelt. Auf den Remotesystemen hatte ich Spielraum.
Übrigens soll meine Synchronisation mit mehreren Systemen funktionieren, zw. 2-10. Die Anwendung auf allen Systemen ist dieselbe, zumindest die Datenbank.
Nur... Wenn Du Beziehungen zwischen den Tabellen hast, mußt Du diese ja immer wieder korrigieren. D.h. Wenn Du die Id umschreibst, müssen, alle Datensätze anderer Tabellen, die sich darauf beziehen, entsprechend geändert werden. Das bedeute wesentlcih mehr Aufwand bei dr Synchronisationsschnittstelle. Das war auch die Schwachstelle bei der zwei-ID-Lösung. Die nächste zentrale Datenbank wird eine Herkunfts-ID aufweisen.
OHHHHH! Bei der Anwendung die ich gerade entwickle ist das zwar nicht so, aber bei einer anderen... Da hab ich ja überhaupt noch nicht dran gedacht! Muß ich jetzt schon wieder alles umschmeißen? Och nö....
Vielleicht trifft Dich heute dieses Problem noch nicht, spätestens wenn Du mehrere Tabellen synchronisierst, die miteinander in Bezug stehen, wird es haarig.
Auweia, da muß ich mir doch glatt was neues überlegen. Da kommt aber wieder eine andere Variante ins Spiel, die ich von Philipp Hasenfratz habe und von der mich Sven Rautenberg nur mit Mühe abbringen konnte:
Ich teile den "ID-Raum" untern den Systemen auf, z.B. System 1 hat IDs von 1.000.000.000 bis 1.999.999.999 usw.
Dann müßte ich die IDs nicht nachträglich verändern. Ich sträube mich aber sehr dagagen, ein komplettes Projekt komplett umzubauen, nämlich dann wenn keien eindeutige ID mehr gegeben ist. Wie gesagt, alle Parameter, Links, Formulare, Header-Weiterleitungen, SELECTS, INSERTS, UPDATES... und bestimmt einiges was ich vergessen werde ;-) Kann man das vielleicht mit Foreign Keys lösen? Ich hatte eh vor erst alle Datensätze zu löschen und zu überschreiben!
Wieso? Das ist doch das einfachste! Du loggst auf beiden Systemen nicht eine Zeit sondern die jeweils eigene System-Zeit und ziehst die dann bei Vergleichen heran!
Und schon wird's kompliziert. Welche Zeit bestimmt Deinen letzten Synchronisationszeitpunkt? Die der zentralen Datenbank, oder die des Remotesystems? oder merkst Du Dir beide Zeiten.
Ich merke mir beide Zeiten, alles andere ist ungenau, egal was Du Dir ausdenkst, es ist und bleibt eine "Stolperfalle".
Naja, eine Lösung gäbe es ja dafür, XNTP. Das wäre sowieso das beste, allerdings mußt Du dann auch sicher sein, daß der immer funktioniert. Ich hatte anfangs schon Problem, wenn der Rechner auf dem die Sync-Engine läuft eine andere Zeit gegenüber dem Datenbanksystem hat.
Das läuft bei mir immer auf jeweils einer Maschine.
vielleicht nicht neutral, aber SQL-Statements finde ich besser
Das bedeutet aber, daß eines der Systeme etwas über das andere wissen muß. Ich habe es dagegen so ausgelegt, daß immer nur das System, auf dem der aktuelle Vorgang läuft, seine eigene Datenbank kennen muß.
OK, vermutlich hast Du das ganze auf einem etwas höheren Level gemacht, ich verwende rundrum MySQL und das wird auch so bleiben. Da die Anwendung auf allen Systemen dieselbe ist, ist auch dei komplette Datenstruktur gleich, daher reicht das Wissen um die eigene Datenstruktur vollkommen aus! Änderungen müssen auf allen Systemen durchgeführt werden.
der Remote-Host wird auch übertragen, der letzte Sync Timestamp wird aber aus der jeweils eigenen speziellen sync-Tabelle ausgelesen, dem client entsprechend
Ich habe es vorgezogen, daß das Remotesystem besser alles über den aktuellen Zustanad weiß, und daß das dem Zentralsystem ziemlich egal sien kann. Im zweifelsfall wurde die Remotedatenbank einfach durch einenen Dump neu angelegt, wobei dann dort auch der Sync-Timestamp eingetragen wurde.
Da bei mir die Datenstruktur überall gleich ist kann ich auch überall die Daten mit einem Dump ersetzen, bis auf die Kleinigkeit das die zu synchronisieren Tabellen ein Feld mit HerkunftsID haben, der den eigenen Standort als Standardwert hat. Dafür schreibe ich aber ein config-Script, welches solche Dinge eben einstellt.
Hier wird es wieder umgekehrt. Das Zentrale System muß viel über das Remotesystem wissen, auhc das empfinde ich als enormen Nachteil.
Wie gesagt, wenn die Datenstruktur gleich ist(auch Tabellennamen, Spaltennamen, Formate, Inhalte), dann reicht das Wissen über die eigene DB. Das habe ich extra gemacht um diese Probleme zu umgehen.
Wobei ich denke, daß die Statements vom Volumen her um nichts kleiner sind als 'meine' Daten, eher etwas mehr. Noch etwas, leere Felder werden bei mir natürlich nicht übertragen, warum auch.
Bei Updates genauso, aber die Inserts sind bei mir kürzer, alleine aufgrund der Schreibweise:
INSERT INTO tabelle (spalte1,spalte2) VALUES
(12,34),
(56,78),
(90,12),
...
Aber Du hast Recht, daran soll es nicht liegen, vermutlich läßt sich Deine Version dafür besser komprimieren, und schon ist es egal! Hast Du das eigentlich auch implementiert, eine Komprimierung?
Hast Du auch eine Verschlüsselung eingesetzt?
Ja, deshalb siehe meine Lösung, da wird eigentlich nur das notwendigst geschickt, ohne zuviel Flexibilität zu verlieren.
Das stimmt schon, ich hatte nur Angst das sowas zu langsam wird, da ich auf einem System an Laufzeiten gebunden bin, wenn dann noch die langen Übertragungszeiten dazu kommen... Wenn ich einmal mein Statements direkt im ersten Schritt noch während des Auslesens der Ursprungs-Datenbank generiere, und über das Kommandozeilen-tool einlese, geht das unheimlich schnell. Bei Deiner Variante brauch ich ja jedesmal erst ein SELECT um zu prüfen ob der Eintrag vorhanden, müßte dann in einer Schleife das Statement generieren und dann noch ein INSERT-Statement.
Wie machst Du das denn eigentlich mit dem Parsen? Wie bekommst Du die Datensätze für eine Tabelle in einen Array? Ich meine wo "splittest" Du? OK, danach kannst Du bei [EOR] splitten, und dann jeweils bei :, vermutlich schreibst Du das dann jeweils als key-value Paar in einen Array, nur was machst Du wenn in den Daten mal ein ":" vorkommt? So Probleme habe ich alle nicht!
[TABELLENNAME]
ID:4711
HERKUNFT:123
NAME:ABCDEF
WERT:1234
MEMO:xyzdsdskdkjdsk
MODFLAG:1
[EOR]
ID:4712
HERKUNFT:123
NAME:ABCDEF
WERT:1234
MEMO:xyzdsdskdkjdsk
MODFLAG:1
[EOR]
...
[ANDERE_TABELLE]
ID:815
HERKUNFT:123
...
Ich denke zwar nicht, dßa meine Lösung unbedingt die beste ist, vor allem da ich doch einiges an Rahmenbedingungen hatte, die andere Wege von vorn herein ausgeschlossen haben. Trotzdem denke ich, daß da einiges auhc für Dein vorhaben drin ist. Wir werden ja sehen, was Du da letztendlich ausbrütest;-)
Ja ich bin auch mal gespannt, vielen Dank für Deine Hilfe, vermutlich hast Du mich vor einem größeren Fehler bewahrt! Velen Dank!
Viele Grüße
Andreas