Синхронизация базы данных клиента SQLite с базой данных сервера MySQL - PullRequest
6 голосов
/ 22 июня 2009

Я создал приложение в xcode с sqlite3.Я хочу создать кнопку с именем sync для синхронизации с моей базой данных MySQL на моем сервере. Любое предложение о процессе синхронизации? Пожалуйста, дайте мне знать.

Ответы [ 6 ]

8 голосов
/ 30 октября 2009

Хорошо, вы понимаете, что это нетривиальная проблема. В прошлом году я написал библиотеку, чтобы сделать это для коммерческого приложения, и потребовалось около 6 месяцев, чтобы доставить его туда, где я был счастлив.

Оставляя в стороне аргумент для использования порта 80 и HTTP (TCP / IP), чтобы избежать проблем с брандмауэром и поддержкой, вам необходимо разработать протокол. Так как мой проект был очень информативным, я использовал двоичный протокол (а не раздутый XML), который мог обрабатывать любые данные. Я также хотел, чтобы он был двунаправленным, чтобы я мог вставлять данные и выполнять запросы. Я использовал CGI / FastCGI на сервере.

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

Хотя этот протокол можно использовать для передачи любых данных, обычно он используется для данных в стиле базы данных, как предполагает ваш вопрос. Чтобы аккомодировать это, я решил использовать подход строк / столбцов к дизайну. Данные хранятся по одной строке за раз, то есть каждый столбец сохраняется для первой строки, а затем все столбцы для строки 2 ... строка n.

Формат данных отдельных столбцов:

' Col1Type          1Bytes - BYTE     ' Data Type (REMSQL_TEXT etc)                
' Col1Len           4Bytes - DWORD    ' Length in bytes the Column Data                            - up to 4.2GB
' Col1Data          nBytes - BYTE     ' String data  

(в С, БАЙТ - ЧАР)

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

REMSQL_NONE = 0    ' DataType undefined
REMSQL_QUAD = 1    ' 64-bit signed integer                
REMSQL_DBLE = 2    ' 64-bit IEEE floating point number
REMSQL_TEXT = 3    ' STRING - (CHAR) string of Ascii Bytes                                     
REMSQL_BLOB = 4    ' BLOB - (CHAR) string of Binary Bytes                                       
REMSQL_NULL = 5    ' NULL - Empty Column

Эти типы данных совпадают с основными типами данных SQLite и численно эквивалентны перечислению основных типов данных SQL3.

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

Заголовок чанка должен содержать такие вещи, как количество строк, количество столбцов, общее количество байтов и т. Д. И т. Д. Если вы используете DWORD (64-разрядные целые числа без знака), то теоретический предел для чанка составляет 4,2 гигабайта, что должно быть достаточно даже для локальных передача по сети.

Для реализации этой функции требуется написание оболочек SQLite / MYSQL. Я использую исключительно протокол BINARY, который занимает немного времени, но вам необходимы следующие функции: Сторона клиента: SendRequest () - отправляет запрос, ждет ответа

Сторона сервера: ProcessRequest () - получает запрос, обрабатывает его и возвращает ответ

В моем случае ответ может быть! 00MB данных или больше. Я извлекаю весь набор данных из MySQL и сохраняю его на диск на сервере. Затем я возвращаю пустой кусок, который содержит метрики набора данных. Затем клиент запрашивает набор данных кусками по 600 Кб, один за другим. Если соединение потеряно, оно просто начинает с того места, где остановилось.

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

В процессе всего этого я пишу очень быстрый класс построения строк, реализацию шифрования AES в ASM и целую библиотеку FastCGI (www.coastrd.com)

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

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

Если вы напишите свое, пожалуйста, напишите здесь о своем опыте!

PS. Попробуйте изменить название, чтобы сделать его более удобным для поиска. Возможно что-то вроде:

"Синхронизация базы данных клиента SQLite с базой данных сервера MySQL"

4 голосов
/ 07 октября 2009

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

3 голосов
/ 20 октября 2009

Я полагаю, вы говорите, что у вас на одном компьютере работает MySql Server, и вы запускаете приложение с экземпляром sqlite и хотите обновить сервер sqlite, если на MySql Server появились новые данные.

Я бы сделал это так

1) Убедитесь, что таблица на вашем компьютере и в приложении имеет одинаковую структуру. Включить последнее обновленное поле

2) Чтобы проверить, кто является самым последним, получите последнюю строку по вашему уникальному ключу, а затем сравните обновленное поле.

3) Когда самое актуальное поле принадлежит серверу, выясните, сколько строк различается, и начните копировать их в цикле do ... while () или по своему усмотрению.

Если вы реализуете этот код как на сервере, так и на клиенте, они могут обновлять друг друга или, если вы предпочитаете, только обновлять клиент.

Особенности зависят от языка, который вы хотите использовать, и количества времени, которое вы хотите потратить на разработку.

0 голосов
/ 11 июля 2011

entropyDb имеет функцию автоматической репликации, которая может справиться с этим

0 голосов
/ 02 ноября 2009

SQuirreL SQL (в Java с использованием Hibernate) имеет подключаемый модуль DBCopy. Это может быть возможно для сценария копии базы данных, используя это. Я не пробовал, но это первое направление, по которому я бы пошел.

0 голосов
/ 28 октября 2009

Несколько вопросов:

  • Вы пытаетесь выполнить двустороннюю синхронизацию или просто извлекаете обновления с сервера?
  • Какие операции обновления допустимы? Вставка / Update / Delete? В реплицируемых базах данных удаления обычно избегают.

Если вам нужно только извлечь вставки / обновления с сервера, вы можете создать скрипт PHP, который будет возвращать операторы SQLite для выполнения. Сценарий php будет принимать параметр последней последовательности / времени обновления от клиента.

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

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