На поднятую вами проблему нельзя ответить в нескольких абзацах или ответить просто. Тем не менее, вот моя попытка...
Во-первых, есть ряд трудностей с принятым вами подходом:
- Клиенты всегда должны быть подключены к сети для создания данных и получения ключей от сервера.
- Если вы создаете разные хранилища (localstorage и REST), весь код приложения, требующий данных, должен просматриваться в обоих хранилищах. Это значительно увеличивает сложность каждой части приложения.
- После создания строки, если вы хотите создать дочерние строки, вы должны дождаться, пока сервер вернет первичный ключ, прежде чем вы сможете ссылаться на него как на внешний ключ в дочерней строке. Для любых умеренно сложных структур данных это становится тяжелым бременем.
- Когда сервер выходит из строя, все клиенты не могут создавать данные.
Вот мой подход. Он использует SequelSphereDB, но большинство концепций можно повторно использовать в других клиентских системах управления данными.
ПЕРВОЕ: используйте UUID для первичных ключей.
Большинство клиентских систем управления данными должны обеспечивать способ создания универсальных уникальных идентификаторов. SequelSphere делает это просто с помощью функции SQL: UUID(). Наличие UUID в качестве первичного ключа для каждой строки позволяет генерировать первичные ключи на любом клиенте в любое время без необходимости связываться с сервером и при этом гарантировать уникальность идентификаторов. Следовательно, это также позволяет приложению работать в автономном режиме, не требуя подключения к серверу во время выполнения. Это также предотвращает отказ сервера от отключения всех клиентов.
ВТОРОЕ: Используйте один набор таблиц, отражающих сервер.
Это скорее требование простоты, чем что-либо еще. Это также требование для следующих двух фундаментальных принципов.
ТРЕТИЙ. Для нисходящей синхронизации небольших наборов данных предпочтительнее полностью обновлять клиентские данные с сервера.
По возможности выполняйте полное обновление данных на клиенте с сервера. Это более простая парадигма, которая приводит к меньшему количеству внутренних проблем с целостностью данных. Основным недостатком является размер данных при передаче.
ЧЕТВЕРТОЕ. Для нисходящей синхронизации больших наборов данных выполняйте «транзакционные» обновления
Здесь мой подход становится немного сложнее. Если наборы данных слишком велики и требуют синхронизации только измененных строк, вы должны найти способ их синхронизации в соответствии с «транзакциями». То есть: вставки/обновления/удаления в том порядке, в котором они выполнялись на сервере, чтобы предоставить простой сценарий для выполнения того же на клиенте.
Желательно иметь на сервере таблицу, записывающую транзакции, которые необходимо синхронизировать с устройством. Если это невозможно, то заказ часто может быть записан на сервере с использованием временных меток в строках и с запросом клиента обо всех изменениях с определенной временной метки. Большой минус: вам нужно будет отслеживать удаленные строки либо путем «логического» удаления, либо путем отслеживания их в их собственной таблице. Тем не менее, изоляция сложности на сервере предпочтительнее, чем распространение ее на всех клиентов.
ПЯТОЕ: для восходящей синхронизации используйте «транзакционные» обновления
Именно здесь SequelSphereDB действительно эффективен: он будет отслеживать для вас все вставки, обновления и удаления, выполненные в таблицах, а затем предоставлять их вернуться к вам во время синхронизации. Он делает это даже при перезапуске браузера, поскольку сохраняет информацию в localstorage/indexeddb. Он даже обрабатывает коммиты и откаты соответствующим образом. Клиентское приложение может взаимодействовать с данными, как обычно, не задумываясь о записи изменений, а затем использовать «Change Trackers» SequelSphereDB для воспроизведения изменений во время синхронизации.
Если вы не используете SequelSphere (а должны), то держите на клиенте отдельную таблицу для записи всех вставок, обновлений и удалений, которые выполняет клиент. Всякий раз, когда клиентское приложение вставляет/обновляет/удаляет строки, создайте их копию в таблице «транзакций». Во время восходящей синхронизации отправьте те. На сервере просто выполните те же действия в том же порядке, чтобы реплицировать данные, которые были на клиенте.
ТАКЖЕ ВАЖНО: всегда выполняйте восходящую синхронизацию перед полным обновлением клиентских таблиц с сервера. :)
Заключение
Я предлагаю стремиться к простоте, а не сложности в максимально возможном количестве мест. Использование UUID для первичных ключей чрезвычайно полезно для этого. Также очень полезно использовать своего рода «трекеры изменений». Использование такого инструмента, как SequelSphereDB, для отслеживания изменений наиболее полезно, но не обязательно для этого подхода.
ПОЛНОЕ РАСКРЫТИЕ: я тесно связан с компанией SequelSphere, но этот продукт действительно не нужен для реализации описанного выше подхода.
person
John Fowler
schedule
29.11.2012