Лучший способ сохранить целостность данных между локальной и удаленной базами данных SQL - PullRequest
4 голосов
/ 31 января 2012

Итак, у меня есть, казалось бы, обычный вопрос, на который я не могу найти ответ.Я пытаюсь найти , что является «наилучшей практикой» для разработки архитектуры базы данных, которая поддерживает данные локально, а затем синхронизирует эти данные с удаленной базой данных, которая совместно используется многими клиентами .Чтобы было понятнее, в этой удаленной базе данных будет много клиентов, которые ее используют.

Например, если бы у меня было настольное приложение, в котором хранились списки дел (в SQL) с отдельными элементами.Затем я хочу иметь возможность отправить эти данные в веб-сервис, который имел «главную» копию всей информации о разных клиентах. Меня не беспокоит проблема синхронизации, так как я просто пытаюсь продумать фактическую архитектуру таблиц клиента и таблиц веб-сервисов

Вот пример того, как я думалоб этом:

База данных клиентов

list
--list_client_id (primary key, auto-increment)
--list_name

list_item
--list_item_client_id (primary key, auto-increment)
--list_id
--list_item_text

Основная веб-база данных (общая для многих клиентов)

list
--list_master_id
--list_client_id (primary key, auto-increment)
--list_name
--user_id


list_item
--list_item_master_id (primary key, auto-increment)
--list_item_remote_id
--list_id
--list_item_text
--user_id

Идея будет заключаться в том, что клиент может создавать списки задач с элементами и синхронизировать их с веб-службой в любой момент времени (т. Е. Если он потеряет соединение с данными и не сможет отправлять информацию допозже ничего не выйдет из строя).Веб-сервис будет записывать записи с идентификаторами клиентов как просто дополнительные поля.Таким образом, клиент может сказать «обновить список № 4 с новым именем», а сервер воспринимает это как «обновить список № 4 пользователя 12 с новым именем».

Ответы [ 3 ]

0 голосов
/ 08 февраля 2012
SERVER:
list
--id
--name
--user_id
--updated_at
--created_from_device_id

Those 2 tables link all records, might be grouped in one table also.
list_ids
--list_id
--device_id
--device_record_id

user_ids
--user_id
--device_id
--device_record_id


CLIENT (device_id=5)
list
--id
--name
--user_id
--updated_at

Это позволит вам сохранять записи как (только показывая соответствующие поля):

server
 list: id=1, name=shopping, user_id=1234
 user: id=27, name=John Doe

 list_ids: list_id=1, device_id=5, device_record_id=999
 user_ids: user_id=27, device_id=5, device_record_id=567

client
 id=999, name=shopping, user_id=567

Таким образом, они совершенно не знают ни одного идентификатора, переводы могут быть выполнены довольно быстро, и вы можете предоставить клиентам только ту информацию и идентификаторы, которые им известны.

0 голосов
/ 18 мая 2014

У меня та же проблема с проектом, над которым я работаю, в моем случае решением было создать дополнительное пустое поле в локальных таблицах с именем 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 может не совпадать с реальным идентификатором ни в локальной, ни в удаленной таблицах, поэтому всякий раз, когда генерируется remote_id, он возвращает сигнал клиентское приложение, запрашивающее обновить локальное поле _id, запускает ранее созданный триггер в sqlite, обновляющий затронутые таблицы. http://www.sqlite.org/lang_createtrigger.html

1 - remote_id генерируется на сервере

2 - возвращает сигнал клиенту

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

Конечно, я также использую поле last_updated, чтобы помочь синхронизации и избежать дублирования синхронизации.

0 голосов
/ 03 февраля 2012

Я думаю, что общая концепция, с которой вы работаете, является верным направлением, но вам, возможно, придется обратить особое внимание на использование столбцов с автоинкрементом.Например, автоматическое увеличение на сервере бесполезно, если клиент является владельцем этого идентификатора.Вместо этого вы, вероятно, хотите, чтобы list.list_master_id был автоинкрементом.Все остальное, что вы упомянули, вполне правдоподобно, хотя сложность может возрасти, если на одного пользователя может быть несколько клиентов.Тогда использование одного автоинкремента, вероятно, недостаточно.Вместо этого вам может понадобиться guid или тип данных, который также включает в себя идентификатор клиента для предотвращения конфликта идентификаторов.

Без дополнительных подробностей было бы трудно предположить, какие другие ситуации вам, возможно, придется рассмотреть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...