Mantenimento dell'integrità referenziale tra un client mobile e un server


21

Quindi ho un sistema relativamente semplice. Un client mobile crea record in un database sqlite che vorrei sincronizzare con un server SQL remoto (condiviso con altri client mobili) . Quindi, quando creo un nuovo record nella tabella sqlite del telefono, invio tale modifica al mio servizio remoto tramite un'API RESTful. Il problema che sto riscontrando è come ordinare le chiavi primarie in modo che non ci siano collisioni nei dati (ovvero un record nel telefono ha la stessa chiave primaria di un record completamente diverso sul server). Qual è la solita "best practice per fare riferimento al record sul client e per fare riferimento allo stesso record sul server?


1
L'idea generale è che il client funge da cache per il server Web, con le modifiche che vengono create nel client, quindi
inviate al

Risposte:


22

La pratica normale è strutturare il database con le uniqueidentifierchiavi (a volte chiamate UUID o GUID). Puoi crearli in due luoghi senza paura realistica della collisione.

Successivamente, l'app per dispositivi mobili deve sincronizzare le tabelle "fact" dal server prima di poter creare nuove righe. Quando crei nuove righe, lo fai localmente e quando esegui nuovamente la sincronizzazione, nuove righe vengono aggiunte al server. Puoi fare la stessa cosa anche con aggiornamenti ed eliminazioni.

Per tenere traccia degli inserti è necessario un timestamp creato sulle righe. Per tenere traccia degli aggiornamenti, è necessario tenere traccia di un timestamp LastUpdate sulle righe. Per tenere traccia delle eliminazioni è necessario un tavolo tombstone.

Si noti che quando si esegue una sincronizzazione, è necessario controllare il time offset tra il server e il dispositivo mobile ed è necessario disporre di un metodo per risolvere i conflitti. Gli inserti non sono un grosso problema (non dovrebbero essere in conflitto), ma gli aggiornamenti potrebbero essere in conflitto e un'eliminazione potrebbe essere in conflitto con un aggiornamento.

Esistono framework per gestire questo tipo di cose, come Microsoft Sync Framework .


il framework di sincronizzazione è ancora vivo
Sadaquat,

7

Scommetto che assolutamente, senza dubbio, non si può avere integrità referenziale tra i due. In particolare, i tuoi utenti si aspettano che l'applicazione mobile funzioni quando è disconnessa?

Esistono due pratiche per questo:

Uno è quello di creare record "provvisori" sul client, quindi quando si sincronizzano con il server il sistema centrale assegna l'ID. Il client può aggiornare il record locale per riflettere ciò.

L'altro è distribuire la creazione dell'ID in modo che (normalmente probabilisticamente) consenta ai clienti di creare l'ID senza collisioni.

Per questo, vai su UUID - v4 è abbastanza improbabile che si scontrino.

Altrimenti, considera qualcosa che mette l'ID univoco del dispositivo mobile nell'ID record. Pertanto, l'ID record potrebbe essere ${imei}-${local sequence number}o qualcosa del genere, in cui l'IMEI garantisce l'univocità e il numero di sequenza locale è solo un normale ID sequenziale del database.



0

Ho lo stesso problema con un progetto a cui sto lavorando, la soluzione nel mio caso era quella di creare un campo nulla annullabile nelle tabelle locali chiamato remote_id. Quando si sincronizzano i record dal database locale al database remoto se remote_id è null, significa che questa riga non è mai stata sincronizzata e deve restituire un ID univoco corrispondente all'ID della riga remota.

Local Table            Remote Table

_id (used locally)
remote_id ------------- id
name      ------------- name

Nell'applicazione client collego le tabelle tramite il campo _id, in remoto utilizzo il campo ID remoto per recuperare dati, eseguire join, ecc.

esempio a livello locale:

Local Client Table       Local ClientType Table      Local ClientType
                         _id
                         remote_id  
_id -------------------- client_id
remote_id                client_type_id -------------- _id
                                                      remote_id
name                    name                          name

esempio da remoto:

Remote Client Table      Remote ClientType Table      Remote ClientType
id -------------------- client_id
                        client_type_id -------------- id
name                    name                          name

Questo scenario, e senza alcun logico nel codice, causerebbe errori di integrità dei dati, poiché la tabella client_type potrebbe non corrispondere all'id reale né nelle tabelle locali o remote, pertanto ogni volta che viene generato un remote_id, restituisce un segnale all'applicazione client chiedendo di aggiornare il campo _id locale, viene attivato un trigger precedentemente creato in sqlite che aggiorna le tabelle interessate. http://www.sqlite.org/lang_createtrigger.html

1- remote_id viene generato nel server

2- restituisce un segnale al client

3- client aggiorna il suo campo _id e attiva un trigger che aggiorna le tabelle locali che si uniscono a _id locale

Ovviamente utilizzo anche un campo last_updated per aiutare le sincronizzazioni ed evitare sincronizzazioni duplicate.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.