Mysql
 sql >> база данни >  >> RDS >> Mysql

Синхронизиране на клиентска база данни на SQLite с база данни на MySQL сървър

Е, разбирате, че това е нетривиален проблем. Написах библиотека, за да постигна това за комерсиално приложение миналата година и отне около 6 месеца, за да го стигна до мястото, където бях доволен от него.

Като оставим настрана аргумента за използване на порт 80 и HTTP (TCP/IP), за да избегнете проблеми със защитната стена и поддръжката, трябва да проектирате протокол. Тъй като моят проект беше много натоварен с данни, аз използвах двоичен протокол (вместо раздутия xml), който може да обработва всякакви данни. Исках също така да бъде двупосочен, за да мога да ВМЕСКАМ данни, както и да изпълнявам заявки. Използвах CGI/FastCGI на сървъра.

Двоичният протокол, който проектирах, е доста прост (винаги по-добър) и разделя големи трансфери на парчета с размер, определен от потребителя (около 600k изглежда е добре). Всяка част има заглавка, последвана от данните.

Въпреки че този протокол може да се използва за предаване на всякакъв вид данни, обикновено се използва за данни за стил на база данни, както предполага вашият въпрос. За да се справя с това, реших да използвам подход на редове/колони към дизайна. Данните се съхраняват един ред в даден момент, което означава, че всяка от колоните се съхранява за ред първи, след това всички колони за ред 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  

(в C BYTE е CHAR)

Това означава, че всяка колона има дескриптор за тип данни. Всички типове данни могат да бъдат представени с:

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 байта, за да се намери някакъв завършващ символ.

Заглавката на Chunk трябва да съдържа неща като брой редове, брой колони, общо байтове и т.н. и т.н. Ако използвате DWORD (неподписани 64-битови цели числа), тогава теоретичното ограничение за парче е 4.2gigs, което би трябвало да е достатъчно дори за предаване на локална мрежа.

Реализацията изисква писане на SQLite/MYSQL обвивки за тази функционалност. Използвам изключително протокола BINARY, което отнема малко време, но по същество се нуждаете от следните функции:Клиентска страна:SendRequest() - Изпраща заявка, чака отговор

От страна на сървъра:ProcessRequest() - Получава заявка, обработва я и връща отговор

В моя случай отговорът може да бъде !00MB данни или повече. Извличам целия набор от данни от MySQL и го записвам на диск на сървъра. След това връщам празна част, която съдържа метриките на набора от данни. След това клиентът изисква набора от данни на парчета от 600k, един по един. Ако връзката се загуби, тя просто продължава откъдето е спряла.

И накрая, наборът от данни беше предимно текст (имена, адреси и т.н.), така че е узрял за компресиране. Сигурността беше много голям проблем в този случай, така че криптирането беше от съществено значение. Това става малко по-сложно за изпълнение, но основно компресирате цялата част, подложка до дължина, която е кратна на блоковите шифри BLOCKSIZE и го криптирате.

В процеса на всичко това пиша много бърз клас за създаване на низове, реализация на AES криптиране в ASM и цяла библиотека FastCGI (www.coastrd.com)

Така че, както казах, нетривиално. Скоро ще направя тази библиотека достъпна. Ако искате да го проверите, изпратете ми имейл.

След като сте написали комуникацията, можете да започнете да проектирате синхронизацията. Бих използвал или хеш за всеки запис, или обикновен булев флаг. Ако нещо се промени на сървъра, просто изпратете целия запис и го презапишете от страна на клиента (ако приемем, че се опитвате да поддържате клиентите синхронизирани...)

Ако пишете своя собствена, моля, публикувайте отново тук за вашия опит!

PS Помислете за промяна на заглавието, за да бъде по-удобно за търсене. Може би нещо като:

„Синхронизиране на клиентска база данни на SQLite с база данни на MySQL сървър“



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql - днес е между две стойности на колони

  2. Каква е разликата между използването на INDEX срещу KEY в MySQL?

  3. Активирайте Python за свързване с MySQL чрез SSH тунелиране

  4. MySQL заявка:Съпоставете стойност, разделена със запетая, с колона, съдържаща низ, разделен със запетая

  5. Трябва ли MySQL да има часова зона на UTC?