Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Синхронизация БД на сервере с локальными копиями 
V
    Опции темы
AXS
Дата 18.3.2010, 06:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 115
Регистрация: 26.9.2008
Где: РК

Репутация: нет
Всего: -1



В общем суть такова - есть БД расположенная на сервере и есть прога юзающая локальные копии этой БД, скажем на домашнем компе, на работе и портабельная версия проги на флэшке.

Например я добавляю некие записи посредством проги на работе, прога записывает данные в свою копию базы и перед закрытием (а также после открытия) синхронизирует свою БД с удалённой.

Вечером я запускаю домашнюю копию проги и после открытия она синхронизируется с удалённой БД получая тем самым данные записи созданные на работе. Перед закрытием, на сервер опять уходят записи изменённые или добавленные дома.

И т д. Таким образом где бы мы ни были, мы всегда получим данные измененные или созданные ранее и сохраним свою работу для использования в будущем.

===============================================================================================

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

У меня единственное что на уме крутится, так это добавить в записи поле куда писать хэш записи. Скажем сливать все поля записи в одну строку и получать её хэш. У каждой записи есть уникальное и не изменяемое поле key. При синхронизации тогда надо сравнить хеши записей ориентируясь по key... Опять же как то надо определить какая запись актуальнее (то есть позже изменена)?

В общем вот что, собсно, прошу помочь - сделать оптимальный алгоритм синхронизации, при котором не придется шерстить все записи...

PS: Может какую то дату/время актуальности сделать?...

Это сообщение отредактировал(а) AXS - 18.3.2010, 11:04
--------------------
<><><> AXS - Live Organizer v1.0  <><><> 0_o
PM MAIL WWW ICQ Skype GTalk   Вверх
Akina
Дата 18.3.2010, 08:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



Цитата(AXS @  18.3.2010,  07:50 Найти цитируемый пост)
 как оптимизировать алгоритм синхронизации, чтобы каждый раз не сравнивать все записи?

Ввести поле Dirty, при любой корректировке писАть туда штамп времени изменения, при синхронизации Null-ить.
В результате посылать на синхронизацию надо только те записи, которые WHERE Dirty IS NOT Null. Штамп времени позволит при одновременном изменении в нескольких копиях разрулить коллизию - автоматом или вручную. Если же коллизии исключены - достаточно Boolean поля.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
AXS
Дата 18.3.2010, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 115
Регистрация: 26.9.2008
Где: РК

Репутация: нет
Всего: -1



Цитата(Akina @ 18.3.2010,  08:54)
Цитата(AXS @  18.3.2010,  07:50 Найти цитируемый пост)
 как оптимизировать алгоритм синхронизации, чтобы каждый раз не сравнивать все записи?

Ввести поле Dirty, при любой корректировке писАть туда штамп времени изменения, при синхронизации Null-ить.
В результате посылать на синхронизацию надо только те записи, которые WHERE Dirty IS NOT Null. Штамп времени позволит при одновременном изменении в нескольких копиях разрулить коллизию - автоматом или вручную. Если же коллизии исключены - достаточно Boolean поля.

Если локальная база "А" внесла запись в серверную базу и поставила штамп времени, 
потом локальная база "В" синхронизировалась с серверной и обNULLила поле, 
то локальная база "С" об этой записи уже не узнает... 
Как то так получается....
--------------------
<><><> AXS - Live Organizer v1.0  <><><> 0_o
PM MAIL WWW ICQ Skype GTalk   Вверх
Akina
Дата 18.3.2010, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



Если удалённых баз несколько - для каждой вводится своё поле Dirty1, Dirty2...
А вообще у СУБД обычно есть свои средства репликации, как правило более эффективные, чем всякие программистские поделки.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
AXS
Дата 18.3.2010, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 115
Регистрация: 26.9.2008
Где: РК

Репутация: нет
Всего: -1



Цитата(Akina @ 18.3.2010,  10:11)
Если удалённых баз несколько - для каждой вводится своё поле Dirty1, Dirty2...
А вообще у СУБД обычно есть свои средства репликации, как правило более эффективные, чем всякие программистские поделки.

Удалённая база одна, а вот локальных несколько, причём заранее неизвестно сколько.

Насчёт встроенных средств, боюсь проблемно будет - локальные базы MS Access + MS Jet (для мобильности), а удалённая MySQL на сервере под линуксом...
--------------------
<><><> AXS - Live Organizer v1.0  <><><> 0_o
PM MAIL WWW ICQ Skype GTalk   Вверх
Earnest
Дата 19.3.2010, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 7
Всего: 183



Цитата(AXS @  18.3.2010,  11:05 Найти цитируемый пост)
Если локальная база "А" внесла запись в серверную базу и поставила штамп времени, 
потом локальная база "В" синхронизировалась с серверной и обNULLила поле, 
то локальная база "С" об этой записи уже не узнает... 

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


--------------------
...
PM   Вверх
AXS
Дата 30.3.2010, 21:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 115
Регистрация: 26.9.2008
Где: РК

Репутация: нет
Всего: -1



Короче отработал я синхронизацию так:

1) Добавил поля HASH и TIMESTAMP в таблицы
2) Создал дополнительную таблицу

I)  Хэш записи высчитывается путём сложения ключевых полей записи.
II) TIMESTAMP используется именно так как подсказал Earnest (отдельный tnx за то ему)
III)  Кроме того хеши записей за каждую отдельно взятую неделю также складываются в строку, высчитывается хэш получившейся строки и записывается в ту самую дополнительную таблицу. (В принципе их тоже можно сложить и получить хэши месяцев или кварталов, но мне пока излишне)

Таким образом сверяя хэши недель в локальной и удалённой базах мы за одну проверку можем убедится в неизменности записей за всю неделю (в большинстве случаев записи месячной и более давности будут изменятся редко, а то и вовсе не будут, но проверить то это мы обязаны)

А) Если хэши недели не совпали, то какая то запись в ней изменена и начинается проверка хэшей каждой записи за эту неделю.

Б) При этом выбираются ключи, хэши и таймштампы с серверной базы, после чего хэши сравниваются с локальными (ориентируясь по ключам (ID записи на сервере))

В) Если хэши записи не совпали, то сравниваются таймштампы: грубо говоря у какой записи таймштамп старше, та и приоритетнее.

Г) Кроме того записи с таким ID может и не быть в локальной базе. Значит такую запись добавил другой клиент (просто записываем запись в локальную базу)

Д) После всего этого выбираются записи уже из локальной базы с серверным ключом равным нулю. Ведь когда запись создаётся локально у неё ещё нет серверного ключа (он присвоится автоинкриментом при первой синхронизации, то есть сейчас)
Выбранные таким образом новые записи записываются на сервер, а свежесозданые ключи возвращаясь пишутся в соответствующие поля записей.

Е) И последняя тонкость: При удалении записи локально, она не удаляется сразу, иначе при следующей же синхронизации будет снова записана с сервера. Сначала в определённое поле пишется пометка на удаление, потом при синхронизации такие записи удаляются сначала с сервера, потом из локальной базы. 

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

(Последний пункт ещё не реализован, поэтому несколько туманно...)

Ну вот вроде и всё... Есть какие то замечания - пишите, всё ещё очень сыро и будет отлаживаться и дорабатываться...

Это сообщение отредактировал(а) AXS - 30.3.2010, 21:10
--------------------
<><><> AXS - Live Organizer v1.0  <><><> 0_o
PM MAIL WWW ICQ Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0645 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.