Синхронизация одной или нескольких баз данных с основной базой данных - внешние ключи - PullRequest
4 голосов
/ 03 марта 2010

Я использую Google Gears, чтобы иметь возможность использовать приложение в автономном режиме (я знаю, что Gears устарела). Проблема, с которой я сталкиваюсь, заключается в синхронизации с базой данных на сервере.

Конкретная проблема - первичные ключи или, точнее, внешние ключи. При отправке информации на сервер я мог легко игнорировать первичные ключи и генерировать новые. Но тогда откуда мне знать, что это за отношения.

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

Edit:
Я думал об этом, и я думаю, что последовательные первичные ключи не лучшее решение, но какие еще есть возможности? Время не кажется правильным из-за столкновений, которые могут произойти.

На ум приходит GUID, это вариант? Похоже, что генерировать GUID в javascript не так просто.

Я могу что-то сделать с помощью естественных или составных ключей. Пока я думаю об этом, это выглядит как лучшее решение. Могу ли я ожидать каких-либо проблем с этим?

Ответы [ 4 ]

3 голосов
/ 13 марта 2010

Это не совсем полный ответ, но, по крайней мере, может дать вам некоторые идеи ...

Вопрос, который вы задаете (и проблема, которую вы пытаетесь решить) не относится к Google Gears и будет действовать для других решений, таких как HTML 5 или системы на основе или Flash / Air.


Эта тема была представлена ​​во время последнего ZendCon несколько месяцев назад. Слайды доступны на слайд-шоу: Планирование синхронизации с локальными базами данных браузера


Просматривая эти слайды, вы увидите заметки о нескольких возможностях, которые могут прийти в голову (некоторые из них действительно пришли вам в голову, или в других ответах) :

  • Использование GUID
  • Композитные ключи
  • Пул первичных ключей (т.е. зарезервировать диапазон ключей заранее)

Конечно, для каждого из них есть свои преимущества ... и недостатки - я не буду их копировать-вставлять: взгляните на слайды; -)


Теперь, в вашей ситуации, какое решение будет лучшим? Трудно сказать, на самом деле - и чем раньше вы подумаете о синхронизации, тем лучше / проще это будет, вероятно: добавление материала в приложение будет намного проще, когда это приложение еще находится на стадии разработки ^^


Во-первых, было бы интересно определить:

  • Ваше приложение обычно подключено, и отключение происходит редко
  • Или если ваше приложение обычно отключено и подключается только время от времени.

Тогда, что вы собираетесь синхронизировать?

  • Данные?
    • Like " Это список всех команд, выполненных этим пользователем "
    • С этими данными, реплицированными на каждое отключенное устройство, разумеется - что каждый может его изменить
    • В этом случае, если один пользователь удаляет строку, а другой добавляет строку, как узнать, какой из них имеет данные " true "?
  • Или действия над этими данными?
    • Как " Я добавляю запись в список команд, сделанных этим пользователем "
    • В этом случае, если один пользователь удаляет строку, а другой добавляет строку, синхронизировать легко, так как вам просто нужно синхронизировать эти два действия с вашей центральной БД
    • Но это не совсем легко реализовать, особенно для большого приложения / системы: каждый раз, когда совершается какое-либо действие, вы должны что-то регистрировать!


Существует также особая проблема, о которой мы обычно не думаем - пока это не произойдет: особенно если ваш процесс синхронизации может занять некоторое время (если у вас много данных, если вы не часто синхронизируете,. ..) , что если синхронизация остановится, когда она еще не закончена?

Например, что если:

  • Пользователь в поезде имеет доступ к сети с некоторой картой 3G
  • Синхронизация начинается
  • есть туннель - и соединение потеряно.

Наличие полусинхронизированных данных может быть не очень хорошим в большинстве ситуаций ...

Итак, вам нужно найти решение и этой проблемы: в большинстве случаев синхронизация должна быть атомарной!

0 голосов
/ 13 марта 2010

Существует ли разумное ограничение на количество объектов, которые клиент может создать при отключении?Одна из возможностей, которую я вижу, - создать своего рода «локальную последовательность».

Когда ваш клиент подключается к центральному серверу, он получает числовой идентификатор, скажем, 7-значный номер (сервер генерирует его как последовательность).

Фактические PK создаются в виде строк, подобных этой: 895051 | 000094 или 895051 | 005694, где первая часть представляет собой семизначный номер, отправленный с сервера, а вторая часть представляет собой управляемую «локальную» последовательностьклиентом.

Как только вы синхронизируете с центральным, вы можете получить новый 7-значный номер и перезапустить вашу локальную последовательность.В общем, это не слишком отличается от того, что вы предлагаете.Это просто делает фактический ПК полностью независимым от личности клиента.

Еще одним бонусом является то, что если у вас есть сценарий, когда клиент никогда не подключался к серверу, он может использовать 000000 | 000094 локально, требовать новый номер с сервера и обновлять ключи на своей стороне перед отправкой обратно.на сервер для синхронизации (это сложно, если у вас много ограничений FK, и это невозможно сделать).

0 голосов
/ 13 марта 2010

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

Не забудьте также настроить уникальный индекс на вашем Client Pk, Client Id, чтобы обеспечить ссылочную целостность любых дочерних таблиц.

0 голосов
/ 06 марта 2010

Я придумал следующее решение:

Каждый клиент получает уникальный идентификатор с сервера. Везде, где есть ссылка на первичный ключ, я использую составной ключ с идентификатором клиента и полем автоинкремента.

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

Я только что обнаружил один недостаток: SQLite не поддерживает автоинкремент для составных первичных ключей, поэтому мне пришлось бы обрабатывать идентификаторы самостоятельно.

...