sql >> Databáze >  >> RDS >> Mysql

Synchronizace klientské databáze SQLite s databází serveru MySQL

Uvědomujete si, že jde o netriviální problém. Minulý rok jsem napsal knihovnu, abych toho dosáhl pro komerční aplikaci, a trvalo asi 6 měsíců, než jsem ji dostal tam, kde jsem s ní byl spokojený.

Pomineme-li argument pro použití portu 80 a HTTP (TCP/IP), abyste se vyhnuli problémům s firewallem a podporou, musíte navrhnout protokol. Protože můj projekt byl velmi náročný na data, šel jsem s binárním protokolem (spíše než s nafouknutým xml), který dokázal zpracovat jakákoli data. Také jsem chtěl, aby to bylo obousměrné, abych mohl VLOŽIT data a také provádět požadavky. Na serveru jsem použil CGI/FastCGI.

Binární protokol, který jsem navrhl, je docela jednoduchý (vždy lepší) a rozděluje velké přenosy na kousky uživatelem definované velikosti (asi 600 k se zdá být dobré). Každý blok má záhlaví, za kterým následují data.

Ačkoli lze tento protokol použít pro přenos jakéhokoli druhu dat, obvykle se používá pro data ve stylu databáze, jak naznačuje vaše otázka. Abych tomu vyhověl, rozhodl jsem se použít k návrhu přístup řádků/sloupců. Data jsou uložena po jednom řádku, což znamená, že každý ze sloupců je uložen pro řádek jedna, poté všechny sloupce pro řádek 2 ... řádek n.

Formát dat jednoho sloupce je:

' 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  

(v C je BYTE CHAR)

To znamená, že každý sloupec má deskriptor datového typu. Všechny datové typy lze reprezentovat pomocí:

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

Tyto datové typy se shodují se základními datovými typy SQLite a jsou numericky ekvivalentní výčtu základních datových typů SQL3.

V tomto návrhu, pokud je pole prázdné (NULL), pak jste pro jeho uložení vzali pouze 5 bajtů. Pokud má pole například 200 bajtů textu, jeho uložení zabere pouze 205 bajtů. Větší výhodou je analýza dat, protože přeskakování sloupců lze provést bez čtení všech 200 bajtů za účelem nalezení nějakého ukončovacího znaku.

Hlavička chunk by měla obsahovat věci jako počet řádků, počet sloupců, celkový počet bajtů atd. Pokud používáte DWORD (neznaménková 64bitová celá čísla), pak teoretický limit pro chunk je 4,2 giga, což by mělo stačit i pro přenos lokální sítě.

Implementace vyžaduje pro tuto funkci zápis obalů SQLite/MYSQL. Používám výhradně BINARY protokol, který zabere trochu času, ale v podstatě potřebujete následující funkce:Strana klienta:SendRequest() - Odešle požadavek, čeká na odpověď

Strana serveru:ProcessRequest() – Přijme požadavek, zpracuje ho a vrátí odpověď

V mém případě může být odezva 100 MB dat nebo více. Načítám celou sadu dat z MySQL a ukládám ji na disk na serveru. Poté vrátím prázdný blok, který obsahuje metriky datové sady. Klient poté požaduje soubor dat v blocích po 600 kB, jeden po druhém. Pokud se spojení ztratí, pokračuje tam, kde skončilo.

A konečně, soubor dat byl většinou text (jména, adresy atd.), takže zralý pro kompresi. Zabezpečení bylo v tomto případě velmi velkým problémem, takže šifrování bylo zásadní. Implementace je trochu složitější, ale v zásadě komprimujete celý blok, pad na délku, která je násobkem blokových šifer BLOCKSIZE, a zašifrujete jej.

V procesu toho všeho píšu velmi rychlou třídu pro vytváření řetězců, implementaci šifrování AES v ASM a celou knihovnu FastCGI (www.coastrd.com)

Takže jak jsem řekl, ne triviální. Tuto knihovnu brzy zpřístupním. Pokud se na to chcete podívat, napište mi.

Jakmile budete mít komunikaci napsanou, můžete začít navrhovat synchronizaci. Buď bych použil hash pro každý záznam, nebo jednoduchý booleovský příznak. Pokud se na serveru cokoliv změní, stačí odeslat celý záznam a přepsat jej na straně klienta (za předpokladu, že se snažíte udržovat klienty synchronizované...)

Pokud napíšete svůj vlastní, napište sem o své zkušenosti!

PS. Zvažte změnu názvu tak, aby byl přátelštější k vyhledávání. Možná něco jako:

"Synchronizace klientské databáze SQLite s databází serveru MySQL"



  1. Volání nedefinované funkce oci_connect()

  2. Získejte názvy tabulek z databáze

  3. SQL Server kontroluje rozlišování velkých a malých písmen?

  4. SQL získat další řádky z agregační funkce