Ich habe vor ungefähr 8 Jahren ein solches System für eine App erstellt und kann einige Möglichkeiten erläutern, wie es sich mit zunehmender App-Nutzung entwickelt hat.
Ich begann damit, jede Änderung (Einfügen, Aktualisieren oder Löschen) von einem Gerät in einer "Verlauf" -Tabelle zu protokollieren. Wenn beispielsweise jemand seine Telefonnummer in der Tabelle "Kontakt" ändert, bearbeitet das System das Feld contact.phone und fügt einen Verlaufsdatensatz mit action = update, field = phone, record = [Kontakt-ID] hinzu. value = [neue Telefonnummer]. Bei jeder Synchronisierung eines Geräts werden die Verlaufselemente seit der letzten Synchronisierung heruntergeladen und auf die lokale Datenbank angewendet. Dies klingt wie das oben beschriebene Muster "Transaktionsreplikation".
Ein Problem besteht darin, IDs eindeutig zu halten, wenn Elemente auf verschiedenen Geräten erstellt werden können. Ich wusste nichts über UUIDs, als ich dies startete, also habe ich automatisch inkrementierende IDs verwendet und einen verschlungenen Code geschrieben, der auf dem zentralen Server ausgeführt wird, um neue IDs zu überprüfen, die von Geräten hochgeladen wurden, und sie bei einem Konflikt in eine eindeutige ID zu ändern Weisen Sie das Quellgerät an, die ID in seiner lokalen Datenbank zu ändern. Nur die IDs neuer Datensätze zu ändern war nicht so schlecht, aber wenn ich zum Beispiel ein neues Element in der Kontakttabelle erstelle, dann erstelle ich ein neues verwandtes Element in der Ereignistabelle, jetzt habe ich Fremdschlüssel, die ich auch brauche überprüfen und aktualisieren.
Schließlich erfuhr ich, dass UUIDs dies vermeiden konnten, aber bis dahin wurde meine Datenbank ziemlich groß und ich befürchtete, dass eine vollständige UUID-Implementierung ein Leistungsproblem verursachen würde. Anstatt vollständige UUIDs zu verwenden, habe ich zufällig generierte alphanumerische Schlüssel mit 8 Zeichen als IDs verwendet und meinen vorhandenen Code zur Behandlung von Konflikten beibehalten. Irgendwo zwischen meinen aktuellen 8-Zeichen-Schlüsseln und den 36 Zeichen einer UUID muss es einen Sweet Spot geben, der Konflikte ohne unnötiges Aufblähen beseitigt. Da ich jedoch bereits über den Konfliktlösungscode verfüge, war es keine Priorität, damit zu experimentieren .
Das nächste Problem war, dass die Verlaufstabelle etwa zehnmal größer war als der gesamte Rest der Datenbank. Dies verteuert die Lagerung und jede Wartung der Verlaufstabelle kann schmerzhaft sein. Wenn Sie die gesamte Tabelle beibehalten, können Benutzer alle vorherigen Änderungen rückgängig machen, aber das fühlte sich wie ein Overkill an. Daher habe ich dem Synchronisierungsprozess eine Routine hinzugefügt. Wenn das Verlaufselement, das ein Gerät zuletzt heruntergeladen hat, nicht mehr in der Verlaufstabelle vorhanden ist, gibt der Server ihm nicht die letzten Verlaufselemente, sondern eine Datei mit allen Daten für dieser Account. Dann habe ich einen Cronjob hinzugefügt, um Verlaufselemente zu löschen, die älter als 90 Tage sind. Dies bedeutet, dass Benutzer Änderungen, die weniger als 90 Tage alt sind, weiterhin rückgängig machen können. Wenn sie mindestens alle 90 Tage synchronisiert werden, werden die Aktualisierungen wie zuvor inkrementell durchgeführt. Aber wenn sie länger als 90 Tage warten,
Durch diese Änderung wurde die Größe der Verlaufstabelle um fast 90% reduziert. Durch die Verwaltung der Verlaufstabelle wird die Datenbank jetzt nur noch doppelt so groß anstatt zehnmal so groß. Ein weiterer Vorteil dieses Systems besteht darin, dass die Synchronisierung bei Bedarf immer noch ohne die Verlaufstabelle funktionieren kann - beispielsweise, wenn ich Wartungsarbeiten durchführen musste, die es vorübergehend offline schalteten. Oder ich könnte verschiedene Rollback-Zeiträume für Konten zu unterschiedlichen Preisen anbieten. Wenn mehr als 90 Tage lang Änderungen zum Herunterladen erforderlich sind, ist die gesamte Datei normalerweise effizienter als das inkrementelle Format.
Wenn ich heute von vorne anfangen würde, würde ich die ID-Konfliktprüfung überspringen und nur eine Schlüssellänge anstreben, die ausreicht, um Konflikte zu beseitigen, mit einer Art Fehlerprüfung für alle Fälle. Die Verlaufstabelle und die Kombination aus inkrementellen Downloads für aktuelle Updates oder einem vollständigen Download bei Bedarf haben jedoch gut funktioniert.