adsl club

Справочник

Форум

Программы

Фильмы

Ресурсы

Файлообмен

Хостинг

Ростелеком
Синхронизация удалённых баз данных.
На страницу 1 2 3
Ответить на тему    Форум АДСЛ КлубаЦИФРОВОЙ ФЛЕЙМ :)ПРОГРАММИРОВАНИЕ
Автор Сообщение
AlexRock
Гуру
СообщениеДобавлено: Сб 6-03-10 : 15-02    Заголовок сообщения: Синхронизация удалённых баз данных. Ответить с цитатой

Подскажите, пожалуйста, каковы общие механизмы, без привязки к платформам и языкам. Мне нужно синхронизировать две БД - одну на сервере в Интернете (я имею к ней полный доступ) и другую - на коммуникаторе, причём пока достаточно односторонней (от сервера к коммуникатору) синхронизации - на коммуникаторе ничего редактировать нельзя будет, только считывать с сервера и из локальной копии серверной БД. Первое, что мне в голову приходит, так это для каждой таблицы завести столбцы типа "Дата последнего редактирования" и потом с коммуникатора опрашивать все строки синзронизируемых таблиц, сравнивая эти даты последнего редактирования. Если дата на коммуне старее, чем на сервере, то эту строку переписываю серверным вариантом этой строки (примерно то же используется в майкрософтовском Synchronization Services, только со всякими наворотами). Ну, и т. д.

Я знаю, что в некоторых СУБД и фреймворках есть встроенные технологии синхронизации, типа майкрософтовской Synchronization Services, но у меня с ней десятки проблем на ровном месте возникают, и я решил подстраховаться, надеясь, что можно самому создать простенький механизм синхронизации.

Я в этой области новичок - никаких СУБД не изучал в ВУЗах - так что меня интересуют вообще теория и стратегии такой синхронизации, а также всякие подводные камни, которые могут на этом пути встериться. Посоветуйте ещё, пожалуйста, где можно об этом почитать, но только без большого количества теории и воды - всё таки мне нужно делать работу, а не экзамен по СУБД и сетям сдавать. ))
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Aprelle
Гуру
СообщениеДобавлено: Сб 6-03-10 : 15-13    Заголовок сообщения: Ответить с цитатой

Фрилансом занимаешься?
В БД подводных камней может быть много.
Как вариант, кроме даты изменения, введи еще поле с порядковым номером, автоинкремент.
Затем придется сравнивать все номера, чтобы отслеживать все удаленные строки.
Во многих БД есть таблицы логов, можно также анализировать их на предмет произведенных изменений.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
AlexRock
Гуру
СообщениеДобавлено: Сб 6-03-10 : 19-39    Заголовок сообщения: Ответить с цитатой

Aprelle писал(а):
Фрилансом занимаешься?

Нет, на дядю. ))
Aprelle писал(а):
Как вариант, кроме даты изменения, введи еще поле с порядковым номером, автоинкремент.

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

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

Я ещё не знаю, какое исключение выдаётся при попытке обращения к удалённым строкам, но по этому исключению думаю отслеживать удалённые строки на сервере, чтобы потом на локальной БД такие же строки удалить. Если этот механизм не сработает, то придётся ещё немного скопировать Synchronization Services - все удалённые на сервере строки помещать в спец. таблицу "Удалённые строки", к которой потом и будет локальная БД обращаться, чтобы у себя такой же набор удалить. Минус в том, что при частом обновлении каталога деталей (если старые будут удаляться) эта таблица разрастётся поболе основной... хотя на сервере место есть, да и не так часто детали обновляются.

Меня больше интересуют вопросы нестабильности канала связи, если объём транзакций будет достаточно большим. Я вообще по протоколу TCP/IP думаю это делать, так я надеюсь, что встроенные механизмы защиты этого протокола от потери данных при разрывах сами смогут всё подобные проблемы разрулить. В том смысле, что, если транзакция не прошла из-за помех, скажем (по вафле запросы будут идти и далее через Интернет), то потом она будет повторятся до тех пор, пока не закончится удачно. Причём мне для настройки именно такого поведения ничего делать не надо будет - всё за меня уже сделано и автоматизировано. Или я не прав? Если что, я использую MS SQL Server на сервере и его же компактную версию (Compact) на коммуникаторе. Но всё осложняется тем, что я практически не осведомлён обо всех возможностях TCP/IP и MS SQL Server в этом плане, так что хотелось бы почитать что-то вроде небольшого руководства "как строить устойчивые к разрывам связи системы для синхронизации баз данных на нестабильных каналах связи". Ну, т. е. чтобы там оговаривались типичные проблемы и возможности их решения, желательно с примерами для разных СУБД и протоколов передачи данных. При этом без готовых решений а-ля "чёрный ящик" - Synchronization Services - ибо самому тоже неплохо было бы знать, как это делать "в коде".

В принципе, это меня интересует, если я не разберусь с Synchronization Services, ибо что-то очень уж трудно для меня заставить её работать - то с Вижаком проблемы, то с сервером.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Estet
Форумчанин
СообщениеДобавлено: Сб 6-03-10 : 20-47    Заголовок сообщения: Ответить с цитатой

Я вот подумал. А если все изменения на удаленной машине записывать в скрипт. А потом скачивать этот скрипт и накатывать на коммуникаторе? Все это делать автоматически естественно. Можно воспользоваться differential backup например(наверное).
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
ultrancux
Продвинутый форумчанин
СообщениеДобавлено: Сб 6-03-10 : 23-12    Заголовок сообщения: Ответить с цитатой

репликация? Это что?
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
AlexRock
Гуру
СообщениеДобавлено: Сб 6-03-10 : 23-59    Заголовок сообщения: Ответить с цитатой

Estet писал(а):
Я вот подумал. А если все изменения на удаленной машине записывать в скрипт. А потом скачивать этот скрипт и накатывать на коммуникаторе?

Я уже думал о том, чтобы все изменения записывать в этакий текстовый файл, где будут отражены все данные об изменённых записях. Но только чем это выгоднее от транзакций напрямую самим мезанизмом СУБД? Тем более, что по мере накопления изменений, этот файл будет расти в объёме и каждая следующая синхронизация потребует скачки всё файла всё большего объёма. А механизм опроса записей таблицы БД на предмет сравнения дат последнего обновления менее затратен по трафику, я считаю. Тем более, что можно весь сеанс синхронизации разбить на несколько транзакций - скажем, каждую таблицу в отдельной транзакции синхронизировать или ограничивать число синхронизируемых строк за одну транзакцию (пожалуй, это будет получше вариантом). Кстати, нужно ещё учесть, что локальная копия серверной БД будет на сотнях устройств в перспективе храниться, и при этом на каждом устройстве копии будут разными, ибо время синхронизации будет произвольным - когда пользователь захочет.

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

Не совсем понял, что вы имеете ввиду. Прочитал в Википедии - тоже не прояснилось. Каждую транзакцию дублировать на все коммуникаторы, чтоли? Я думаю, для сотен произвольно подключающихся к серверу устройств это не подойдёт.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Estet
Форумчанин
СообщениеДобавлено: Вс 7-03-10 : 01-30    Заголовок сообщения: Ответить с цитатой

ИМХО.
Надо создать на сервере таблицу, строки которой будут идентифицировать каждого пользователя и дату последней синхронизации. Создать хранимые процедуры, которые бы доставали последние изменения в базе на основе даты последней синхронизации. Ну а там как угодно вам: либо Sql-транзакциями, либо файлом со скриптом получаете данные с сервера.
Туда - запрос на выполнение хранимой процедуры с датой и идентификатором пользователя, назад - последние обновления.
Данные из таблиц удалять не надо, а добавить в каждой таблице столбец "Deleted".
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
AlexRock
Гуру
СообщениеДобавлено: Вс 7-03-10 : 12-54    Заголовок сообщения: Ответить с цитатой

Estet
Кажется, неплохой вариант. ))

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

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

1) запрос клиента к серверу;
2) получение таблицы результатов на сервере;
3) отсылание таблицы результатов клиенту;
5) запись таблицы результатов клиентом в свою копию БД.

Вот на этапе 2) вы предлагаете ещё включить операцию создания физической таблицы результатов (причём учтите, что при каждом акте редактирования серверной БД придётся для всех клиентов их таблицы с накапливаемыми изменениями обновлять, что не есть хорошо). По-моему, нужно минимизировать любое создание таблиц результатов в ПЗУ, сохраняя их только в ОЗУ во время сеанса синхронизации. В идеале должно быть всего две БД в ПЗУ - серверная на сервере и клиентеская на клиенте, без всяких файлов скриптов и желательно без хранимых процедур на сервере. Я вообще буду, скорее всего, сами запросы и код обработки результатов с сервера писать на LINQ to SQL, а не на чистом SQL, так что эти "хранимые процедуры" будут на самом деле кодом клиентской программы на коммуникаторе, посему не желательно на сервере оставлять какую-нибудь свою логику, чтобы не писать для сервера вообще никакого кода - там будут чисто внутренние механизмы СУБД работать (ну, не считая редактора БД). Как вам такой подход?
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Estet
Форумчанин
СообщениеДобавлено: Вс 7-03-10 : 13-38    Заголовок сообщения: Ответить с цитатой

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

1. Почему лучше хранить дату на сервере, а не передавать в запросе? Это позволит вам отдавать пользователям только то, что им предназначено, а не то, что они хотят. Можно например более раннюю дату в запросе забить и получить больше данных либо лишних. Если это не критично, то можно так не делать.

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

Как-то так.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Estet
Форумчанин
СообщениеДобавлено: Вс 7-03-10 : 13-43    Заголовок сообщения: Ответить с цитатой

Linq? не знаю, не пользовался....
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
AlexRock
Гуру
СообщениеДобавлено: Вс 7-03-10 : 14-56    Заголовок сообщения: Ответить с цитатой

Estet писал(а):
Можно например более раннюю дату в запросе забить и получить больше данных либо лишних.

Это не так - клиенту будет доступна только кнопка "Синхронизировать", в обработчике которой будет забит код синхронизации с использованием даты последней синхронизации. Можно, конечно, пытаться взломать программу и исправить дату последней синхронизации (её, кстати, можно тоже хранить в БД либо в каком-нибудь файле на клиенте), но это уже другой вопрос (безопасности). Хотя, хранить данные о дате последней синхронизации на сервере может показаться более удобным, однако здесь есть минус - придётся отслеживать новых клиентов как-то - либо администратору вводить их в таблицу клиентов, либо придумать механизм автоматической регистрации новых клиентов на сервере при первом обращении к нему. Но это не главная проблема. ))
Estet писал(а):
2. Почему хранимая процедура, а не опять же запрос?

во-первых, не передается открытым текстом сам запрос.

во-вторых, он не хранится на дейвасе, значит, его нельзя модифицировать.

в-третьих, будет передаваться меньше трафика от клиента к серверу.

Спасибо, это я обдумаю ещё.
Estet писал(а):
Linq? не знаю, не пользовался....

Извиняюсь, это я лишнее сказал - для кода синхронизации мы ЛИНК использовать не будем, скорее всего.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Aprelle
Гуру
СообщениеДобавлено: Вс 7-03-10 : 16-20    Заголовок сообщения: Ответить с цитатой

AlexRock писал(а):
>Как вариант, кроме даты изменения, введи еще поле с порядковым номером, автоинкремент.

Ну, это-то само собой (ты же про т. н. "айдишники" (Id) говоришь?).

AlexRock писал(а):
>Затем придется сравнивать все номера, чтобы отслеживать все удаленные строки.

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

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


Estet писал(а):
Создать хранимые процедуры, которые бы доставали последние изменения в базе на основе даты последней синхронизации.

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

Так что как минимум нужно смотреть на дополнительный id-шник.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
AlexRock
Гуру
СообщениеДобавлено: Вс 7-03-10 : 17-40    Заголовок сообщения: Ответить с цитатой

Aprelle писал(а):
Ты забываешь про то, что данные в пользовательских таблицах могут быть удалены или испорчены непосредственно на пользовательском устройстве, серверная БД таким способом не сможет произвести правильную синхронизацию.

Удалены или испорчены, если пользователь взломает программу и БД, ибо у пользователя на клиенте не предусмотрено никаких средств редактировпния БД, кроме кнопки "Синхронизация". Ну, а за непредусмотренный доступ к БД и программе пользователя клиента я не отвечаю - сломают, сами потом за это отвечать будут.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Aprelle
Гуру
СообщениеДобавлено: Вс 7-03-10 : 18-16    Заголовок сообщения: Ответить с цитатой

он не взломает,
он сломает
и сам того не заметит
банальная порча данных на флэшке
тебе полную синхронизацию в любом случае нужно реализовать
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
AlexRock
Гуру
СообщениеДобавлено: Вс 7-03-10 : 19-10    Заголовок сообщения: Ответить с цитатой

Aprelle писал(а):
банальная порча данных на флэшке

тебе полную синхронизацию в любом случае нужно реализовать

Это я не предусмотрел. Тогда я думаю, что проще будет не синхронизацию в этом случае сделать, а добавить опцию типа "Скачать полную базу данных". Скачать и заменить файл будет проще, чем все строки во всех таблицах проверять, я думаю. Да и не факт, что в СУБД есть внутренний механизм защиты от порчи секторов, на которых файл БД записан, так что лучше уж просто "скачать и заменить".
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Aprelle
Гуру
СообщениеДобавлено: Вс 7-03-10 : 20-17    Заголовок сообщения: Ответить с цитатой

AlexRock писал(а):
Тогда я думаю, что проще будет не синхронизацию в этом случае сделать, а добавить опцию типа "Скачать полную базу данных".

это тоже самое, вопрос в том, что если кто-то до тебя механизм выдачи компактной базы уже реализовал, то конечно проще.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Estet
Форумчанин
СообщениеДобавлено: Вс 7-03-10 : 20-51    Заголовок сообщения: Ответить с цитатой

Кстати, для идентификации строк можно использовать Guid, тогда не придется вводить дополнительные identity-столбцы.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Estet
Форумчанин
СообщениеДобавлено: Вс 7-03-10 : 20-54    Заголовок сообщения: Ответить с цитатой

При порче базы поможет переустановка приложения.
При физической порче даже "скачать полную базу данных" не поможет - файл базы будет находиться ровно на том же месте.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
AlexRock
Гуру
СообщениеДобавлено: Вс 7-03-10 : 21-26    Заголовок сообщения: Ответить с цитатой

Estet писал(а):
Кстати, для идентификации строк можно использовать Guid, тогда не придется вводить дополнительные identity-столбцы.

Я не понял, о чём вы. Айдишники у меня будут хотя бы потому, что нужно строки нумеровать (для идентификации строк), а ещё будет уникальный каталожный номер детали, который не я придумал, а на производстве. Итого, у меня два идентификатора на деталь - один идентифицирует её в БД как строку, а второй - вообще в жизни. )) Я думаю, этого пока достаточно.
Estet писал(а):
При физической порче даже "скачать полную базу данных" не поможет - файл базы будет находиться ровно на том же месте.

Ну, а если удалить сначала повреждённый файл, а затем на его место новый скачать? Ведь привязка к файлу БД на клиенте у меня идёт по абсолютному пути, определяемому во время установки, так что можно просто заменить файл "за кулисами" и дальше работать, я думаю.
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Aprelle
Гуру
СообщениеДобавлено: Вс 7-03-10 : 21-42    Заголовок сообщения: Ответить с цитатой

AlexRock писал(а):
Я думаю, этого пока достаточно

недостаточно
ещё версию детали для данного каталожного номера нужно
 Наверх
Посмотреть профиль / Отправить личное сообщение Отправить личное сообщение  
Показать сообщения:   
Ответить на тему    Форум АДСЛ КлубаЦИФРОВОЙ ФЛЕЙМ :)ПРОГРАММИРОВАНИЕ Часовой пояс: GMT + 7
На страницу 1 2 3
Страница 1 из 3

 

 
Аватары: Вкл|Выкл   ЮзерИнфо: Вкл|Выкл   Подписи: Вкл|Выкл
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете вкладывать файлы
Вы можете скачивать файлы