Mam więc stosunkowo prosty system. Mobilny klient tworzy rekordy w bazie danych SQLite, które chciałbym być synchronizowane do zdalnego serwera SQL (który jest dzielony z innymi klientami telefonii komórkowej) . Więc kiedy tworzę nowy rekord w tabeli sqlite telefonu, następnie wypycham tę zmianę do mojej zdalnej usługi poprzez RESTful API. Problem, który mam, polega na tym , jak zamówić klucze podstawowe, aby nie doszło do kolizji w danych (tj. Rekord w telefonie ma ten sam klucz podstawowy, co zupełnie inny rekord na serwerze). Jaka jest zwykle „najlepsza praktyka odnosząca się do rekordu na kliencie i do tego samego rekordu na serwerze?
sql
web-services
JoeCortopassi
źródło
źródło
Odpowiedzi:
Normalną praktyką jest tworzenie struktury bazy danych za pomocą
uniqueidentifier
kluczy (czasem nazywanych UUID lub GUID). Możesz je tworzyć w dwóch miejscach bez realistycznego strachu przed kolizją.Następnie aplikacja mobilna musi zsynchronizować tabele „faktów” z serwerem, zanim będzie można utworzyć nowe wiersze. Kiedy tworzysz nowe wiersze, robisz to lokalnie, a kiedy ponownie synchronizujesz, nowe wiersze są dodawane do serwera. Możesz zrobić to samo z aktualizacjami i usuwaniem.
Aby śledzić wstawki, musisz mieć utworzony znacznik czasu w swoich wierszach. Aby śledzić aktualizacje, musisz śledzić znacznik czasu LastUpdate w swoich wierszach. Aby śledzić usunięcia, potrzebujesz tabeli nagrobków.
Pamiętaj, że podczas synchronizacji musisz sprawdzić przesunięcie czasowe między serwerem a urządzeniem mobilnym i musisz mieć metodę rozwiązywania konfliktów. Wkładki nie są niczym wielkim (nie powinny powodować konfliktów), ale aktualizacje mogą powodować konflikty, a usunięcie może powodować konflikt z aktualizacją.
Istnieją ramy do obsługi tego rodzaju rzeczy, takie jak Microsoft Sync Framework .
źródło
Założę się, że absolutnie, bez wątpienia, nie można mieć wzajemnej integralności referencyjnej. W szczególności, czy użytkownicy oczekują, że aplikacja mobilna będzie działać po jej odłączeniu?
Istnieją dwie praktyki:
Jednym z nich jest utworzenie „tymczasowych” rekordów na kliencie, a następnie po zsynchronizowaniu ich z serwerem system centralny przypisuje identyfikator. Klient może zaktualizować rekord lokalny, aby to odzwierciedlić.
Drugim jest to, że dystrybuujesz tworzenie identyfikatorów w sposób, który (zwykle probabilistycznie) pozwala klientom tworzyć identyfikatory bez kolizji.
Aby to zrobić, przejdź do UUID - v4 raczej nie koliduje.
W przeciwnym razie rozważ coś, co umieszcza unikalny identyfikator urządzenia mobilnego w identyfikatorze rekordu. Tak więc twoim identyfikatorem rekordu może być
${imei}-${local sequence number}
coś takiego, gdzie IMEI zapewnia unikalność, a lokalny numer sekwencyjny jest po prostu normalnym sekwencyjnym identyfikatorem bazy danych.źródło
Oprócz odpowiedzi Daniela Pittmana jedną z możliwości byłoby przypisanie każdemu klientowi unikalnego identyfikatora klienta i uczynienie z niego identyfikatora będącego częścią klucza podstawowego.
źródło
Mam ten sam problem z projektem, nad którym pracuję, rozwiązaniem w moim przypadku było utworzenie dodatkowego pola zerowego w lokalnych tabelach o nazwie remote_id. Podczas synchronizacji rekordów z lokalnej do zdalnej bazy danych, jeśli identyfikator_zdalny ma wartość NULL, oznacza to, że ten wiersz nigdy nie został zsynchronizowany i musi zwrócić unikalny identyfikator pasujący do identyfikatora zdalnego wiersza.
W aplikacji klienckiej łączę tabele według pola _id, zdalnie używam zdalnego pola id do pobierania danych, wykonywania połączeń itp.
przykład lokalnie:
przykład zdalnie:
Ten scenariusz i brak logiki w kodzie spowodowałby błędy integralności danych, ponieważ tabela typu klient może nie pasować do rzeczywistego identyfikatora w tabelach lokalnych lub zdalnych, dlatego za każdym razem, gdy identyfikator zdalny jest generowany, zwraca sygnał do aplikacji klienckiej z prośbą o aktualizację lokalnego pola _id, to uruchamia wcześniej utworzony wyzwalacz w sqlite aktualizujący dotknięte tabele. http://www.sqlite.org/lang_createtrigger.html
1- zdalny_id jest generowany na serwerze
2- zwraca sygnał do klienta
3- klient aktualizuje swoje pole _id i uruchamia wyzwalacz, który aktualizuje lokalne tabele, które dołączają do lokalnego _id
Oczywiście używam również pola last_updated, aby ułatwić synchronizację i uniknąć powielonych synchronizacji.
źródło