Підтримка референтної цілісності між мобільним клієнтом і сервером


21

Тож у мене відносно проста система. Мобільний клієнт створює записи в базі даних SQLite , що я хотів би синхронізований на віддалений сервер SQL (який спільно з іншими мобільними клієнтами) . Отже, коли я створюю нову запис у таблиці sqlite телефону, я переношу цю зміну до моєї віддаленої служби через API RESTful. Проблема, яку я маю, полягає в тому, як я замовляю первинні ключі, щоб не було зіткнень даних (тобто запис у телефоні має той же первинний ключ, що і зовсім інший запис на сервері). Яка звичайна "найкраща практика для посилання на запис на клієнта та для посилання на той самий запис на сервері?


1
Ідея перезахисту полягає в тому, що клієнт виконує функцію кешу веб-сервера, при цьому зміни створюються в клієнті, а потім переносяться на веб-сервер
JoeCortopassi

Відповіді:


22

Звичайна практика полягає в структуруванні вашої бази даних за допомогою uniqueidentifierключів (іноді їх називають UUID або GUID). Ви можете створити їх у двох місцях без реалістичного страху перед зіткненням.

Далі, ваш мобільний додаток повинен синхронізувати "фактичні" таблиці з сервером, перш ніж ви зможете створювати нові рядки. Коли ви створюєте нові рядки, ви робите це локально, а при повторній синхронізації нові рядки додаються на сервер. Те ж саме можна зробити і з оновленнями та видаленням.

Для відстеження вставок вам потрібна Створена часова позначка на рядках. Для відстеження оновлень потрібно відстежувати часові позначки LastUpdate на своїх рядках. Для відстеження видалених знадобиться таблиця надгробних плит.

Зауважте, що під час синхронізації потрібно перевірити зсув часу між сервером та мобільним пристроєм, і вам потрібно мати спосіб вирішення конфліктів. Вставки не є великою справою (вони не повинні конфліктувати), але оновлення можуть конфліктувати, а видалення може суперечити оновленням.

Існують рамки для обробки подібних речей, такі як Microsoft Sync Framework .


синхронізована система ще жива
Садакват

7

Б'юсь об заклад, що ви абсолютно без сумнівів не можете мати референтну цілісність між ними. Зокрема, чи очікують ваші користувачі, коли мобільний додаток буде працювати при відключенні?

Для цього є дві практики:

Одне полягає у створенні "тимчасових" записів на клієнті, а потім при синхронізації їх із сервером центральна система має призначити ідентифікатор. Клієнт може оновити локальний запис, щоб це відобразити.

Інша полягає в тому, що ви поширюєте створення ідентифікаторів таким чином, що (як правило, імовірнісно) дозволяє клієнтам створювати ідентифікатор без зіткнень.

Для цього перейдіть до UUID - v4 навряд чи зіткнуться.

В іншому випадку розглянемо те, що ставить унікальний ідентифікатор мобільного пристрою в ідентифікатор запису. Отже, ваш ідентифікатор запису може бути ${imei}-${local sequence number}чимось таким, де IMEI забезпечує унікальність, а локальний номер послідовності - це лише звичайний послідовний ідентифікатор бази даних.


2

Окрім відповіді Даніеля Пітмена , одна можливість полягає в тому, щоб сервер призначив кожному клієнтові унікальний ідентифікатор клієнта та зробив ідентифікатор клієнта частиною первинного ключа.


0

У мене те саме питання з проектом, над яким я працюю, у моєму випадку рішенням було створити додаткове нульове поле в локальних таблицях з назвою remote_id. Якщо синхронізувати записи з локальної у віддалену базу даних, якщо remote_id недійсний, це означає, що ця рядок ніколи не була синхронізована і їй потрібно повернути унікальний ідентифікатор, що відповідає віддаленому ідентифікатору рядка.

Local Table            Remote Table

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

У клієнтській програмі я посилаю таблиці таблиць у полі _id, віддалено використовую поле віддаленого ідентифікатора для отримання даних, приєднання до ін.

Приклад локально:

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

Приклад віддалено:

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

Цей сценарій і без будь-якої логіки в коді може спричинити збої цілісності даних, оскільки таблиця_типу client_type може не відповідати дійсному ідентифікатору ні в локальній, ні в віддаленій таблиці, для цього кожен раз, коли генерується віддалений_id, він повертає сигнал клієнтській програмі з проханням оновити локальне поле _id, це запускає створений раніше тригер у sqlite, оновлюючи постраждалі таблиці. http://www.sqlite.org/lang_createtrigger.html

1- remote_id генерується на сервері

2- повертає сигнал клієнту

3- клієнт оновлює своє поле _id та запускає тригер, який оновлює локальні таблиці, що приєднуються до локальних _id

Звичайно, я також використовую поле last_update, щоб допомогти синхронізації та уникнути дублювання синхронізацій.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.