AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Synchronisation zwischen Datenbanken - Ideen?
Thema durchsuchen
Ansicht
Themen-Optionen

Synchronisation zwischen Datenbanken - Ideen?

Ein Thema von jf_stgt · begonnen am 30. Mai 2011 · letzter Beitrag vom 31. Mai 2011
Antwort Antwort
Seite 1 von 2  1 2      
jf_stgt

Registriert seit: 26. Sep 2008
33 Beiträge
 
Delphi 2007 Professional
 
#1

Synchronisation zwischen Datenbanken - Ideen?

  Alt 30. Mai 2011, 12:50
Datenbank: Firebird/MySQL • Version: 2.1 • Zugriff über: -
Guten Tach,

wir haben eine Anwendung im Umlauf, die Daten zwischen einer lokalen Firebird- und einer online MySQL-Datenbank austauscht (repliziert).
Ist u.a. ein Kalender der hier so abgegelichen wird.
Klappt auch soweit ganz gut.
Es wird bei jeder Änderung ein Zeitstempel im jeweiligen Datensatz gesetzt und ein Sync-Prozess holt alle Änderungen (seit letztem Sync) ab und verschiebt diese an die Gegenstelle.
Die Uhrzeiten zwischen lokal und Online DB werden dabei synchron gehalten.

Jetzt gibt es seltenst (vielleicht 1 von 100 oder 1 von 1000 Terminen) den Fall dass ein Satz nicht synchronisiert wird. Der Termin fehlt dann halt online oder wird lokal nicht rausgelöscht, etc.

Problem ist auch noch, dass mehrere Windows Rechner (Firebird) die gleiche MySQL Datenbank synchronisieren. Eine Änderung an Platz1 wird dann auf Platz2 verteilt usw.

Wie handhabt ihr das mit der Synchronisation? Ich will jetzt keine Codebeispiele sondern eher Ideen etc.

Viele Grüße,
Jürgen Findeis
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.366 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Synchronisation zwischen Datenbanken - Ideen?

  Alt 30. Mai 2011, 13:33
Hi Delphi 2-Developer *fg*

und du bist dir sicher, dass der Termin nicht bei der Sync zwischen den einzelnen Firebird-Stationen flöten geht? Wie überwachst Du eigentlich das löschen? Bekommt der Datensatz ne Löschmarkierung oder wird der aus der Tabelle entfernt?

Wenn Du den gleich raus löscht - wie stellst Du dann sicher, dass ein zweiter Client, bei dem der DS dann noch da ist, diesen nicht wieder aufnimmt?

Grüße
  Mit Zitat antworten Zitat
jf_stgt

Registriert seit: 26. Sep 2008
33 Beiträge
 
Delphi 2007 Professional
 
#3

AW: Synchronisation zwischen Datenbanken - Ideen?

  Alt 30. Mai 2011, 14:09
Hi Delphi 2-Developer *fg*

und du bist dir sicher, dass der Termin nicht bei der Sync zwischen den einzelnen Firebird-Stationen flöten geht? Wie überwachst Du eigentlich das löschen? Bekommt der Datensatz ne Löschmarkierung oder wird der aus der Tabelle entfernt?

Wenn Du den gleich raus löscht - wie stellst Du dann sicher, dass ein zweiter Client, bei dem der DS dann noch da ist, diesen nicht wieder aufnimmt?

Grüße
Hallo Lemmy,

[OT]schön von Dir zu hören[/OT].
Ja, irgendwo muss der Satz verloren gehen. Ich überwache schon ob das INSERT etc. geklappt hat aber irgendeine Lücke muss es ja geben.
Beim Löschen wird in einer speziellen Löschtabelle vermerkt dass Satz 0815 entfernt ist. Auch diese Info wird mit einem Zeitstempel versehen. The Same Procedure...

Grüße,
jf_stgt
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#4

AW: Synchronisation zwischen Datenbanken - Ideen?

  Alt 30. Mai 2011, 15:12
Ich kann mir nicht vorstellen, dass soetwas als Clientoperation in einem heterogenen Umfeld robust funktioniert. Allein schon verteilte Transaktionen innerhalb eines Systems können tückisch sein, abgesehen von der Synchronisationslogik.

Ich würde es bei heterogenen DB mit einem Application Server versuchen.
Gruß, Jo
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.366 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Synchronisation zwischen Datenbanken - Ideen?

  Alt 30. Mai 2011, 17:39
[OT]schön von Dir zu hören[/OT].
dito... wollte mich mal wieder bei dir melden.. wir sollten uns irgend wann mal wieder treffen



Beim Löschen wird in einer speziellen Löschtabelle vermerkt dass Satz 0815 entfernt ist. Auch diese Info wird mit einem Zeitstempel versehen. The Same Procedure...
Ok, das wäre meine Vermutung gewesen, dass sich hier die Updates gegenseitig aufheben.... Ein App-Server wäre sicherlich ganz nett, nur bei deiner Konfiguration vermutlich schwer umzusetzen. Was ich mir vorstellen könnte: Du syncronisierst ja aktuell in 2 Ebenen: Einmal horizontal zwischen den Firebird-Installationen und einmal Vertikal zur MySQLDB. Wie wäre es die MySQL als "Master" zu verwenden und alle syncen nur noch mit der.... Somit reduzierst Du die Anzahl der Übergänge und kannst ggf. mit der Überwachung der MySQL DB die SChwachstelle finden...

Grüße
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#6

AW: Synchronisation zwischen Datenbanken - Ideen?

  Alt 30. Mai 2011, 18:27
[QUOTE=Lemmy;1103784]
Du syncronisierst ja aktuell in 2 Ebenen: Einmal horizontal zwischen den Firebird-Installationen und einmal Vertikal zur MySQLDB.
Ist das wirklich so? Ich dachte es läuft alles über die mySql und die Firebird bekommen die Änderungen der "Nachbarstationen" über die Master mySql.
Gruß, Jo
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.366 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Synchronisation zwischen Datenbanken - Ideen?

  Alt 30. Mai 2011, 19:35
[QUOTE=jobo;1103788]
Du syncronisierst ja aktuell in 2 Ebenen: Einmal horizontal zwischen den Firebird-Installationen und einmal Vertikal zur MySQLDB.
Ist das wirklich so? Ich dachte es läuft alles über die mySql und die Firebird bekommen die Änderungen der "Nachbarstationen" über die Master mySql.
Stimmt, das habe ich falsch gelesen... Die MySQL ist schon der master... hm...
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#8

AW: Synchronisation zwischen Datenbanken - Ideen?

  Alt 30. Mai 2011, 21:10
So als Idee zur Synchronisieren...
Eine Tabelle mit Adressdaten (Namen, Strasse, PLZ, Ort, Land, Tel, EMail) wird unabhängig voneinander
auf Notebooks im Aussendienst befüllt und soll auf die gemeinsame Tabelle auf'm Server synchronisiert werden.

Alle Felder werden zu einem String verkettet und darüber ein Hashwert (MD4, MD5, SHA-40) errechnet:
Delphi-Quellcode:
//
hashstring := Trim(name1)+'|'+Trim(name2)+'|'+Trim(strasse)+'|'+...'|'+Trim(EMail);
hashvalue := HexString(CalcMD4(hashstring));
Der Hashvalue wird zusätzlich zu den Adressdaten in einem eigenen, indizierten Feld gespeichert.
Der Hashvalue muss nicht zwingend der Primärschlüssel der Tabelle sein, sondern ist ggf. nur ein Surrogatschlüssel.
Die einzelnen Felder werden vor dem Zusammenbau mit Trim() bearbeitet, damit Leerzeichen am Anfang oder Ende keine Rolle spielen.
Es hängt vom Einzelfall ab, ob man zusätzlich auch noch UpperCase() anwenden sollte.
Das Trennzeichen (hier '|') ist wichtig, damit die Position der Felder fixiert wird.
Ausserdem wichtig: das Design der Tabelle muss von Anfang an passen; nachträgliches Hinzufügen von Felder
ist schwierig, da eine Kollision der Hashwerte droht.

Mit dem Hashvalue Feld gibt es ein eindeutiges Kriterium auf Grund dessen Synchronisiert werden kann.

Löschen von Datensätzen:
Die Datensätze werden nicht wirklich gelöscht, sondern nur mit dem Boolean-Feld "Deleted" markiert.
Alle Datensätze bleiben daher quasi für immer erhalten.
Diese können irgendwann mit DELETE FROM AdressTabelle WHERE Deleted<>0 endgültig gelöscht werden.

Die Tabelle sieht dann also so aus:
Code:
PKey      int
HashValue varchar(32)
LastChange DateTime
Created   DateTime
Deleted   Bool (oder TinyInt oder Byte)
Nutzdaten1 ....
Nutzdaten2 ....
  Mit Zitat antworten Zitat
gmc616

Registriert seit: 25. Jun 2004
Ort: Jena
627 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: Synchronisation zwischen Datenbanken - Ideen?

  Alt 31. Mai 2011, 00:19
Problem ist auch noch, dass mehrere Windows Rechner (Firebird) die gleiche MySQL Datenbank synchronisieren. Eine Änderung an Platz1 wird dann auf Platz2 verteilt usw.
Kurze Frage, damit ich das korrekt verstanden habe: Du synchronisierst EINE Firebird-DB (Win-Client) mit EINER MySQL-DB (online), oder MEHRERE Firebird-DB's (eine pro Client) mit EINER MySQL-DB?

Sollte letzteren der Fall sein, muß ich fragen: Wieso? Ist doch Quatsch!

Ich denke aber, der erste Fall wird zutreffen sein, oder?
Dann stell ich Dir die Frage: Wieso synchronisieren die einzelnen Win-Clients die MySQL-DB?
Wenn jeder Client die MySQL-DB synchronisiert, muß das (vom Gefühl her schon) in die Hose gehen!

Die Idee von SX2008 würde ich _so_ eher nicht verfolgen.
Einen Hashwert über die Adresse zur Synchronisation von Terminen würde ich nicht verwenden. Das Eine hat (im Prinzip) nichts mit dem Anderen zu tun! Adressen können sich ändern! Und das tun sie heufiger, als man als Entwickler denkt.

Selbst wenn man sagt, Okay, der Hashwert wird einmalig erzeugt, beim Anlegen beispielsweise. Die Praxis zeigt, das der EndNutzer gern im Eifer des Gefechtes (Telefonat, Kundengespräch usw.) nur einen Namen (z.B. "Frau Müller") als Adresse anlegt, evtl. einen Termin dazu, und erst später die komplette Adresse nachträgt. Den EndNutzer zur Eingabe der komplette Adresse zu "zwingen" ist eher kontra-produktiv und das Thema wird schnell auf wieder auf deinem Desktop liegen.

Dein DB-Konzept zur Synchronisation hört sich recht gut an.
Was ich allerdings ändern würde, wäre das nicht die Clients die Synchronisation der MySQL-Db vornehmen, sondern das das Ganze an einer zentralen Stelle passiert. Das könnte ein System-Dienst auf dem lokalen DB-Server übernehmen.

Dann brauchen deine Termine einen eindeutigen ID. Deshalb verpasst du den Terminen neben dem Zeitstempel, der die letzte Änderung des Termins beschreibt (nennen wir ihn Änderungsstempel), einen weiteren Zeitstempel, der die Erstellung des Termins beschreibt, mit einer zusätzlichen Kennung in welcher DB der Termin erstellt wurde. Den nennen wir "Erstellstempel" oder einfach ID, dann das wäre dann einer.
Wichtig: Für beide Zeitstempel nutzt du die Zeit des jeweiligen DB-Servers, nicht die des Clients! D.h. im SQL-Statement Now()!!
Die zusätzlich DB-Kennung deswegen, weil die Zeiten der beiden DB's bzw. deren Server nicht zu 100% synchron sein werden.

Den Surrogatschlüssel ala Hashwert, den SX2008 beschreibt, den hättest du dann mit dem Erstellstempel, sprich ID, unabhängig von der Adresse. Und der ist mit Sicherheit eindeutig und enthält sogar mehr Information!

Kurz um: Lass die Synchronisation von einem zentralen Dienst auf dem lokalen DB-Server übernehmen und Dir dürfte kein Termin mehr durch die Lappen gehen. Dadurch, das nun jeder Termin einen eindeutigen ID (Erstellstempel) besitzt, entscheidet der Änderungsstempel, welcher Termin "Master" ist.

Geändert von gmc616 (31. Mai 2011 um 01:06 Uhr) Grund: Noch mal kurz durchdacht ... so sollte es passen
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Synchronisation zwischen Datenbanken - Ideen?

  Alt 31. Mai 2011, 00:32
Der Hashwert ist zwar ganz nett, aber dann muss jeder Client die gesamten Hashwerte vom Server laden, vergleichen und dann den passenden Datensatz nochmals vom Server holen.
Das mag bei wenigen Datensätzen und Clients funktionieren ... aber wenn die Anzahl Datensätze/Clients zunimmt kann man sich auch schön die Bandbreite damit verhageln.

Hier meine Vorschläge zur Synchronisation mit minimalem Overhead:

Zeitstempel

Der Client fragt beim Server alle Datensätze ab, die neuer als der letzte Zeitstempel sind.
Von diesen Daten wird der aktuellste Zeitstempel (vom Server vergeben) als letzter Zeitstempel beim Client gespeichert (nicht die Uhrzeit der letzten Abfrage!)

Hauptproblem bei der Synchronisierung via Zeitstempel bleibt aber die Auflösung des Zeitstempels.
Ein MySQL Server schafft ja (je nach Hardware) mehr als einen Datensatz pro Millisekunde zu speichern.
xxx1 Client A schreibt Datensatz
xxx2 Client B bekommt die Datensätze geliefert (höchster Zeitstempel xxx)
xxx3 Client A schreibt Datensatz
Bei der nächsten Abfrage bekommt Client B aber nicht den 2. Datensatz von A geliefert, denn dieser Datensatz hat ja auch den Zeitstempel xxx obwohl er nach der Abfrage von Client B geschrieben wurde.

Somit müsste also die Abfrage nicht Zeitstempel > xxx lauten, sondern Zeitstempel >= xxx.
Damit bekommt man aber wieder ein entsprechenden Overhead, den man evtl. vermeiden möchte/muss.

Ein Ausweg aus diesem Zeitstempel-Dilemma geht dann nur über

Update-Liste pro Client

In einer Update-Tabelle werden alle Änderungen der Haupt-Tabelle auf dem Server (per Trigger) in diese Update-Tabelle eingetragen. Der Client fragt mit dieser Tabelle die Datensätze ab und löscht dann die verarbeiteten Sätze aus der Tabelle.

Dadurch hat man dann auch das Weitergeben von Löschsätzen charmant gelöst, denn diese können sofort aus der Haupttabelle entfernt werden.
Müssen mehrere Tabellen synchronisiert werden, dann eben den Tabellen-Namen mit in die Update-Tabelle, oder eine UUID als ID verwenden.
Code:
ClientID PK
RecordID PK
DeleteFlag
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:45 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