2009-06-22 4 views
7

J'ai créé une application dans xcode avec sqlite3.Je veux créer un bouton nommé sync pour synchroniser avec ma base de données mysql dans mon serveur. Des suggestions sur le processus de synchronisation? S'il vous plaît, faites-moi savoir.Synchronisation d'une base de données client SQLite avec une base de données MySQL

+0

Êtes-vous prêt à la création d'une synchronisation chute des tables? – Macarse

+0

oui ... cela signifie que je veux synchroniser avec le serveur chaque fois que j'en aurai besoin ... grâce à la transaction sans fil ne pas connecter l'iphone au PC – user123589

+0

Est-ce une synchronisation bidirectionnelle? Les enregistrements peuvent-ils être créés, lus, mis à jour et supprimés, à la fois sur le serveur et entre les clients? (Astuce: vous voulez répondre "non" à cette question si vous le pouvez.) – cduhn

Répondre

4

Utilisez un service Web sur le serveur pour renvoyer à la fois un numéro de version de schéma et un dernier timestate de mise à jour. Si le client n'est pas à jour, il passe un second appel pour obtenir le schéma mis à jour et/ou les nouvelles données.

3

Je crois que vous dites que vous avez un serveur MySql fonctionnant sur un ordinateur et que vous exécutez une application avec une instance sqlite et que vous voulez mettre à jour le serveur sqlite s'il y a de nouvelles données sur le serveur MySql.

je le ferais de cette façon

1) Assurez-vous que la table sur votre ordinateur et sur l'application ont la même structure. Inclure un dernier champ mis à jour

2) Pour vérifier qui est le plus à jour, obtenez la dernière ligne par votre clé unique, puis comparez le champ mis à jour.

3) Lorsque le champ le plus à jour appartient au serveur, déterminez le nombre de lignes différentes et commencez à les copier dans une boucle do ... while() ou selon vos préférences.

Si vous implémentez ce code sur le serveur et sur le client, ils peuvent se mettre à jour les uns les autres ou si vous préférez uniquement mettre à jour le client.

Les spécificités dépendent de la langue que vous souhaitez utiliser et du temps que vous souhaitez mettre en développement.

+0

C'est intéressant et je veux en savoir plus. parce que je ne sais pas vraiment comment commencer. J'ai mySql Server fonctionnant sur un ordinateur et j'ai une application avec une instance sqlite. Je veux créer un bouton Sync dans mon application qui va télécharger les nouvelles données du serveur MySQL. – ludo

+0

Je suis désolé, je n'ai pas répondu. Je n'ai pas le temps de passer du temps à surpasser la pile comme je le faisais auparavant. –

0

Quelques questions:

  • essayez-vous une synchronisation bidirectionnelle, ou tout simplement tirer des mises à jour du serveur?
  • Quelles opérations de mise à jour sont acceptables? Insérer/Mettre à jour/Supprimer? Dans les bases de données répliquées, les suppressions sont généralement évitées.

Si vous avez seulement besoin de retirer des insertions/mises à jour du serveur, vous pouvez créer un script PHP qui retournera les instructions SQLite à exécuter. Le script php prendrait un paramètre de la dernière séquence/heure de mise à jour du client.

Si vous envisagez d'effectuer une synchronisation bidirectionnelle, vous devez penser aux fusions et à la résolution des conflits. Dans les deux cas, il est préférable que chaque partie ait une file d'attente de transaction. Il suffit d'enregistrer chaque instruction CRUD exécutée sur la base de données. Lors de la synchronisation, appliquez ces instructions, puis tronquez la file d'attente.

8

Wel vous vous rendez compte que c'est un problème non trivial. J'ai écrit une bibliothèque pour accomplir ceci pour une application commerciale l'année dernière et il a fallu environ 6 mois pour l'obtenir là où j'étais heureux avec elle. En dehors de l'argument d'utilisation du port 80 et HTTP (TCP/IP) pour éviter les problèmes de pare-feu et de prise en charge, vous devez concevoir un protocole. Depuis mon projet était très intesive de données, je suis allé avec un protocole binaire (plutôt que le xml bloated) qui pourrait gérer toutes les données. Je voulais aussi que ce soit bidirectionnel afin que je puisse insérer des données et exécuter des requêtes. J'ai utilisé CGI/FastCGI sur le serveur. Le protocole binaire que j'ai conçu est assez simple (toujours mieux) et casse les gros transferts en morceaux d'une taille définie par l'utilisateur (environ 600k semble être bon). Chaque bloc a un en-tête suivi des données.

Bien que ce protocole puisse être utilisé pour la transmission de tout type de données, il est généralement utilisé pour les données de style de base de données, comme votre question le suggère. Pour y remédier, j'ai décidé d'utiliser une approche lignes/colonnes pour la conception. Les données sont stockées une ligne à la fois, chacune des colonnes est stockée pour la ligne un, puis toutes les colonnes pour la ligne 2 ... ligne n.

Le format d'une donnée unique de colonnes est la suivante:

' 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 

(en C, un BYTE est CHAR)

Cela signifie que chaque colonne comporte un descripteur de type de données. Tous les types de données peuvent être représentées avec:

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 

Ces types de données co-incide avec SQLite types de données fondamentales et sont Numériquement équivalent à l'énumération SQL3 fondamentales DataTypes.

Dans cette conception, si un champ est vide (NULL), vous n'avez pris que 5 octets pour le stocker. Si un champ a 200 octets de texte par exemple, cela ne prend que 205 octets pour le stocker. Le plus grand avantage est d'analyser les données, car il est possible d'ignorer les colonnes sans lire les 200 octets pour trouver un caractère de terminaison. L'en-tête Chunk doit contenir des éléments tels que le nombre de lignes, le nombre de colonnes, le nombre total d'octets, etc. Si vous utilisez DWORDs (entiers 64 bits non signés), la limite théorique pour un fragment est de 4.2gigs. transmission de réseau local.

L'implémentation nécessite l'écriture de wrappers SQLite/MYSQL pour cette fonctionnalité. J'utilise le protocole BINARY exclusivement, ce qui prend un peu de temps, mais vous avez essentiellement besoin des fonctions suivantes: Côté client: SendRequest() - Envoie une requête, attend une réponse

Côté serveur: ProcessRequest() - Reçoit la requête, les processus et renvoie la réponse

Dans mon cas, la réponse peut être! 00MB de données ou plus. Je récupère l'intégralité de l'ensemble de données de MySQL et l'enregistre sur le disque sur le serveur. Ensuite, je retourne un morceau vide qui contient les métriques de jeu de données. Le client demande alors l'ensemble de données en morceaux de 600k, un par un. Si la connexion est perdue, elle reprend juste là où elle s'était arrêtée. Finalement, l'ensemble de données était principalement composé de texte (adresses de noms, etc.), donc mûr pour la compression. La sécurité était un très gros problème dans ce cas, donc le cryptage était essentiel. Cela devient un peu plus compliqué à implémenter, mais en gros vous comprimez tout le bloc, le pad à une longueur qui est un multiple des chiffrements de bloc BLOCKSIZE et le chiffrez.

Dans le processus de tout cela, j'écris une classe de constructeur de chaîne très rapide, une implémentation de cryptage AES en ASM, et une bibliothèque (www.coastrd.com)

FastCGI ensemble Comme je l'ai dit, non trivial . Je vais bientôt rendre cette bibliothèque disponible. Si vous voulez vérifier, envoyez-moi un email.

Une fois la communication écrite, vous pouvez commencer à concevoir la synchronisation. J'utiliserais un hachage pour chaque enregistrement, ou un simple drapeau booléen. Si quelque chose change sur le serveur, il suffit d'envoyer l'enregistrement complet et de le remplacer du côté client (en supposant que vous essayez de garder les clients synchronisés ...)

Si vous écrivez le vôtre, veuillez poster ici votre expérience !

PS. Pensez à changer le titre à plus de recherche convivial .. Peut-être quelque chose comme:

"Synchronisation d'une base de données client SQLite avec une base de données du serveur MySQL"

0

SQuirreL SQL (en Java en utilisant Hibernate) a un plugin DBCopy à lui. Il pourrait être possible d'écrire une copie de base de données en utilisant ceci. Je n'ai pas essayé, mais c'est la première direction que j'irais.

0

entropyDb dispose d'une fonction de réplication automatique qui pourrait gérer cette

Questions connexes