2009-06-22 18 views
7

Utworzyłem aplikację w xcode z sqlite3. Chcę utworzyć przycisk o nazwie sync do synchronizacji z moją bazą danych mysql na moim serwerze. Wszelkie sugestie dotyczące procesu synchronizacji? Proszę daj mi znać.Synchronizacja bazy danych klienta SQLite z bazą danych serwera MySQL

+0

Czy jesteś gotów, aby zsynchronizować Creation jest zrzucenie tabel? – Macarse

+0

tak ... to oznacza, że ​​chcę zsynchronizować się z serwerem, ilekroć będę go potrzebować ... przez transakcję bezprzewodową nie łączę iPhone'a z PC – user123589

+0

Czy jest to synchronizacja dwukierunkowa? Czy można tworzyć, czytać, aktualizować i usuwać rekordy, zarówno na serwerze, jak i na kliencie, pomiędzy synchronizacjami? (Podpowiedź: chcesz odpowiedzieć "nie" na to pytanie, jeśli to możliwe.) – cduhn

Odpowiedz

4

Użyj usługi internetowej na serwerze, aby zwrócić zarówno numer wersji schematu, jak i ostatnią aktualizację sygnatury czasowej. Jeśli klient jest nieaktualny, wykonuje drugie połączenie, aby uzyskać zaktualizowany schemat i/lub nowe dane.

3

Wierzę, że mówisz, że masz serwer MySql działający na jednym komputerze i używasz aplikacji z instancją sqlite i chcesz zaktualizować serwer sqlite, jeśli są nowe dane na serwerze MySql.

chciałbym zrobić to w ten sposób

1) Upewnij się zarówno w tabeli na komputerze i na aplikacji mają taką samą strukturę. Dodaj ostatnio zaktualizowane pole 2) Aby sprawdzić, kto jest najbardziej aktualny, pobierz ostatni wiersz za pomocą unikalnego klucza, a następnie porównaj zaktualizowane pole.

3) Gdy najaktualniejsze pole należy do serwera, należy ustalić, ile wierszy jest różnych i rozpocząć ich kopiowanie w pętli do ... while() lub jak wolisz.

Jeśli zaimplementujesz ten kod zarówno na serwerze, jak i na kliencie, wówczas mogą się wzajemnie aktualizować lub jeśli wolisz tylko aktualizować klienta.

Szczegóły zależą od języka, którego chcesz użyć i czasu, jaki chcesz poświęcić na rozwój.

+0

To ciekawe i chcę usłyszeć więcej. ponieważ tak naprawdę nie wiem, jak zacząć. Mam serwer mySql uruchomiony na jednym komputerze i mam aplikację qith z instancją sqlite. Chcę utworzyć w mojej aplikacji przycisk Synchronizuj, który pobierze nowe dane z serwera MySQL. – ludo

+0

Przykro mi, że nie odpowiedziałem. Nie mam czasu, żeby spędzać czas na przepełnieniu stosu, tak jak kiedyś. –

0

kilka pytań:

  • Czy próbując dwukierunkową synchronizację, lub po prostu wyciągając aktualizacji z serwera?
  • Jakie operacje aktualizacji są dopuszczalne? Wstaw/aktualizuj/usuń? W replikowanych bazach danych zwykle unika się usuwania.

Jeśli chcesz tylko pobrać inserty/aktualizacje z serwera, możesz utworzyć skrypt PHP, który zwróci instrukcje SQLite do wykonania. Skrypt php pobierałby parametr ostatniej sekwencji/czasu aktualizacji od klienta.

Jeśli planujesz synchronizację dwukierunkową, musisz pomyśleć o scalaniu i rozwiązywaniu konfliktów. Na dwa sposoby najlepiej jest dla każdej strony mieć kolejkę transakcji. Po prostu zapisz każdą instrukcję CRUD wykonaną na bazie danych. Podczas synchronizacji zastosuj te instrukcje, a następnie skróć kolejkę.

8

Uświadom sobie, że to nie jest trywialny problem. W zeszłym roku napisałem bibliotekę, aby zrealizować to w przypadku aplikacji komercyjnej, a dotarcie do miejsca, w którym byłem z niej zadowolony zajęło mi około 6 miesięcy.

Pomijanie argumentu dotyczącego używania portów 80 i HTTP (TCP/IP) w celu uniknięcia zapory i problemów z obsługą, należy zaprojektować protokół. Ponieważ mój projekt był bardzo intesywny, przeszedłem z binarnym protokołem (zamiast nadętego xml), który mógł obsłużyć dowolne dane. Chciałem również, aby był dwukierunkowy, aby móc INSERT danych, a także wykonywać żądania. Użyłem CGI/FastCGI na serwerze.

Zaprojektowany przeze mnie protokół binarny jest dość prosty (zawsze lepszy) i dzieli duże transfery na porcje o rozmiarze zdefiniowanym przez użytkownika (około 600k wydaje się być dobrym). Każdy fragment ma nagłówek, a następnie dane.

Mimo że ten protokół może być używany do przesyłania jakichkolwiek danych, zwykle jest używany do danych stylu bazy danych, jak sugeruje twoje pytanie. Aby to zaakceptować, postanowiłem zastosować podejście wierszy/kolumn do projektu. Dane są przechowywane jeden wiersz na raz, co oznacza, że ​​każda z kolumn jest przechowywana dla pierwszego rzędu, a następnie dla wszystkich kolumn dla wiersza 2 ... wiersza n.

Format pojedynczych danych kolumn:

' 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 

(w C, bajt jest znaki)

Oznacza to, że każda z kolumn zawiera deskryptor typu. Wszystkie typy danych mogą być reprezentowane przez:

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 

Te typy danych incide wspólnie z SQLite typów danych fundamentalnych i są numerycznie równoważne SQL3 podstawowe typy danych wyliczenie.

W tym projekcie, jeśli pole jest puste (NULL), zapisano tylko 5 bajtów. Jeśli na przykład pole zawiera 200 bajtów tekstu, zapisanie go zajmuje tylko 205 bajtów. Większą korzyścią jest parsowanie danych, ponieważ pomijanie kolumn można wykonać bez czytania wszystkich 200 bajtów, aby znaleźć charakter kończący.

Nagłówek Chunk powinien zawierać takie elementy, jak liczba wierszy, liczba kolumn, całkowite bajty itp. Jeśli używasz DWORD (niepodpisane 64-bitowe liczby całkowite), teoretyczny limit dla porcji wynosi 4,2 Giga, co powinno wystarczyć nawet dla transmisja lokalnej sieci.

Implementacja wymaga napisania obwolut SQLite/MYSQL dla tej funkcji. Używam wyłącznie protokołu BINARY, który zajmuje trochę czasu, ale zasadniczo potrzebujesz następujących funkcji: Strona klienta: SendRequest() - Wysyła żądanie, czeka na odpowiedź

Strona serwera: ProcessRequest() - Odbiera żądanie, procesy to i zwraca odpowiedź

W moim przypadku odpowiedź może wynosić: 00MB danych lub więcej. Pobieram cały zestaw danych z MySQL i zapisuję go na dysku na serwerze. Następnie zwracam pustą porcję zawierającą dane zestawu danych. Klient następnie żąda zestawu danych w porcjach po 600 KB, jeden po drugim. Jeśli połączenie zostanie utracone, odbiera się tam, gdzie zostało przerwane.

Wreszcie zbiór danych zawierał głównie tekst (adresy nazw itp.), Które zostały dojrzałe do kompresji. Bezpieczeństwo było bardzo dużym problemem w tym przypadku, więc szyfrowanie było niezbędne. To staje się nieco bardziej skomplikowane do implementacji, ale zasadniczo kompresujesz cały fragment, pad na długość, która jest wielokrotnością szyfrów blokowych BLOCKSIZE i zaszyfrujesz.

W procesie tym wszystkim piszę bardzo szybki ciąg klasy Builder, implementację szyfrowania AES w ASM, i cała biblioteka FastCGI (www.coastrd.com)

Tak jak powiedziałem, nie trywialne . Niedługo udostępnię tę bibliotekę. Jeśli chcesz to sprawdzić, napisz do mnie.

Po zapisaniu komunikacji można rozpocząć projektowanie synchronizacji. Chciałbym użyć skrótu dla każdego rekordu lub prostej flagi boolowskiej. Jeśli coś zmieni się na serwerze, po prostu wyślij cały rekord i zastąp go po stronie klienta (zakładając, że próbujesz synchronizować klientów ...)

Jeśli piszesz sam, opublikuj tutaj informacje o swoich doświadczeniach !

PS. Rozważ zmianę tytułu, aby być bardziej przyjazne dla wyszukiwarek .. Może coś takiego:

„Synchronizacja bazy danych SQLite klienta z serwerem bazy danych MySQL”

0

SQuirreL SQL (w Javie przy użyciu Hibernate) ma DBCopy wtyczki do niego. Możliwe, że będzie można skryptować kopię bazy danych za pomocą tego. Nie próbowałem tego, ale to jest pierwszy kierunek, do którego zmierzam.

0

entropyDb posiada funkcję automatycznej replikacji, które może obsłużyć to

Powiązane problemy