Mempertahankan integritas referensial antara klien seluler dan server

21

Jadi saya punya sistem yang relatif sederhana. Sebuah klien mobile menciptakan catatan dalam database sqlite yang saya ingin telah disinkronisasikan ke SQL server jauh (yang bersama dengan klien mobile lainnya) . Jadi ketika saya membuat catatan baru di tabel sqlite ponsel, saya kemudian mendorong perubahan itu ke layanan jarak jauh saya melalui RESTful API. Masalah yang saya alami, adalah bagaimana cara memesan kunci primer sehingga tidak ada tabrakan dalam data (yaitu catatan di telepon memiliki kunci primer yang sama dengan catatan yang sama sekali berbeda di server). Apa yang biasa "praktik terbaik untuk merujuk catatan pada klien, dan untuk merujuk catatan yang sama di server?

JoeCortopassi
sumber
1
Gagasan yang terlalu melengkung, adalah bahwa klien bertindak sebagai cache untuk server web, dengan perubahan yang dibuat pada klien, kemudian didorong ke server web
JoeCortopassi

Jawaban:

22

Praktik normal adalah menyusun basis data Anda dengan uniqueidentifierkunci (kadang-kadang disebut UUID atau GUID). Anda dapat membuatnya di dua tempat tanpa takut tabrakan yang realistis.

Selanjutnya, aplikasi Seluler Anda perlu menyinkronkan tabel "fakta" dari server sebelum Anda dapat membuat baris baru. Ketika Anda membuat baris baru, Anda melakukannya secara lokal, dan ketika Anda menyinkronkan lagi, baris baru ditambahkan ke server. Anda dapat melakukan hal yang sama dengan pembaruan dan penghapusan juga.

Untuk melacak sisipan, Anda perlu cap waktu Dibuat pada baris Anda. Untuk melacak pembaruan, Anda perlu melacak cap waktu Pembaruan Terakhir pada baris Anda. Untuk melacak penghapusan, Anda memerlukan tabel batu nisan.

Perhatikan bahwa ketika Anda melakukan sinkronisasi, Anda perlu memeriksa waktu offset antara server dan perangkat seluler, dan Anda harus memiliki metode untuk menyelesaikan konflik. Sisipan bukan masalah besar (mereka seharusnya tidak bertentangan), tetapi pembaruan dapat bertentangan, dan penghapusan dapat bertentangan dengan pembaruan.

Ada kerangka kerja untuk menangani hal semacam ini, seperti Kerangka Kerja Microsoft Sync .

Scott Whitlock
sumber
adalah framework sinkronisasi yang masih hidup
Sadaquat
7

Saya yakin Anda benar-benar, tanpa pertanyaan tidak dapat memiliki integritas referensial di antara keduanya. Secara khusus, apakah pengguna Anda mengharapkan aplikasi seluler berfungsi ketika terputus?

Ada dua praktik untuk ini:

Salah satunya adalah membuat catatan "sementara" pada klien, dan kemudian ketika Anda menyinkronkannya ke server minta sistem pusat menetapkan ID. Klien dapat memperbarui catatan lokal untuk mencerminkan hal itu.

Yang lain adalah bahwa Anda mendistribusikan pembuatan ID dengan cara yang (biasanya probabilistically) memungkinkan klien untuk membuat ID tanpa tabrakan.

Untuk itu, buka UUID - v4 tidak mungkin berbenturan.

Kalau tidak, pertimbangkan sesuatu yang memasukkan ID perangkat seluler yang unik dalam ID rekaman. Jadi, ID rekaman Anda mungkin ${imei}-${local sequence number}atau sesuatu, di mana IMEI memastikan keunikan, dan nomor urut lokal hanyalah ID basis data berurutan normal.

Daniel Pittman
sumber
2

Selain jawaban Daniel Pittman , satu kemungkinan adalah server akan menetapkan masing-masing klien ID klien yang unik, dan menjadikan ID Klien bagian dari kunci utama.

FrustratedWithFormsDesigner
sumber
0

Saya memiliki masalah yang sama dengan proyek yang sedang saya kerjakan, solusi dalam kasus saya adalah membuat bidang nullable tambahan di tabel lokal bernama remote_id. Ketika menyinkronkan catatan dari database lokal ke jarak jauh jika remote_id adalah nol, itu berarti bahwa baris ini tidak pernah disinkronkan dan perlu mengembalikan id unik yang cocok dengan id baris jarak jauh.

Local Table            Remote Table

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

Dalam aplikasi klien saya menautkan tabel dengan bidang _id, jarak jauh saya menggunakan bidang id jarak jauh untuk mengambil data, bergabung, dll.

contoh lokal:

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

contoh jarak jauh:

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

Skenario ini, dan tanpa logika apa pun dalam kode, akan menyebabkan kegagalan integritas data, karena tabel client_type mungkin tidak cocok dengan id asli baik di tabel lokal atau jauh, karenanya setiap kali remote_id dibuat, ia mengembalikan sinyal ke aplikasi klien meminta untuk memperbarui bidang _id lokal, ini memicu pemicu yang sebelumnya dibuat di sqlite memperbarui tabel yang terpengaruh. http://www.sqlite.org/lang_createtrigger.html

1- remote_id dibuat di server

2- mengembalikan sinyal ke klien

3- klien memperbarui bidang _id-nya dan mengaktifkan pemicu yang memperbarui tabel lokal yang bergabung dengan _id lokal

Tentu saja saya juga menggunakan bidang last_updated untuk membantu sinkronisasi dan untuk menghindari duplikat sinkronisasi.

spacebiker
sumber