将SQLite客户端数据库与MySQL服务器数据库同步

时间:2009-06-22 07:01:12

标签: iphone mysql cocoa-touch sqlite

我用sqlite3.在xcode中创建了一个应用程序。我想创建一个名为sync的按钮,以便与我服务器中的mysql数据库同步。有关同步过程的任何建议吗?请告诉我。

6 个答案:

答案 0 :(得分:8)

很高兴你意识到这是一个非常重要的问题。我去年为一个商业应用程序编写了一个库来实现这个目标,花了大约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.2gig,即使对于本地也应该足够网络传输。

实现需要为此功能编写SQLite / MYSQL包装器。我只使用BINARY协议,这需要一点时间,但您基本上需要以下功能: 客户端:SendRequest() - 发送请求,等待响应

服务器端:ProcessRequest() - 接收请求,处理它并返回响应

在我的情况下,响应可以是!00MB或更多数据。我从MySQL检索整个数据集并将其保存到服务器上的磁盘。然后我返回一个包含数据集指标的空块。然后,客户端逐个请求600k的数据集。如果连接丢失,它只会从中断处继续。

最后,数据集主要是文本(名称地址等),因此非常适合压缩。在这种情况下,安全性是一个非常大的问题,因此加密至关重要这实现起来要复杂一些,但基本上你压缩整个块,填充块长度是块密码BLOCKSIZE的倍数并加密它。

在这一切的过程中,我编写了一个非常快速的字符串构建器类,ASM中的AES加密实现,以及整个FastCGI库(www.coastrd.com)

正如我所说,非常重要。我将很快推出这个图书馆。如果您想查看,请给我发电子邮件。

一旦编写了通信,就可以开始设计同步。我要么为每条记录使用哈希,要么使用简单的布尔标志。如果服务器上有任何变化,只需发送整个记录并在客户端覆盖它(假设您试图保持客户端同步......)

如果您自己编写,请在此回复您的体验!

PS。考虑将标题更改为更友好的搜索。也许类似于:

“将SQLite客户端数据库与MySQL服务器数据库同步”

答案 1 :(得分:4)

使用服务器上的Web服务返回架构版本号和上次更新的时间戳。如果客户端已过期,则会再次调用以获取更新的架构和/或新数据。

答案 2 :(得分:3)

我相信你说你在一台计算机上运行了一个MySql Server,并且你正在运行一个带有sqlite实例的应用程序,如果MySql Server上有新数据你想要更新sqlite服务器。

我会这样做

1)确保计算机和应用程序上的表格具有相同的结构。包括最后更新的字段

2)要检查最新的用户是否按唯一密钥获取最后一行,然后比较更新后的字段。

3)当最新的字段属于服务器时,然后确定有多少行不同并开始在do ... while()循环中复制它们,或者你喜欢的。

如果您在服务器和客户端上实现此代码,那么他们可以相互更新,或者您只是更新客户端。

具体细节取决于您要使用的语言以及您希望投入开发的时间。

答案 3 :(得分:0)

几个问题:

  • 您是尝试双向同步,还是仅从服务器提取更新?
  • 可以接受哪些更新操作?插入/更新/删除?在复制数据库中,通常会避免删除。

如果您只需要从服务器中提取插入/更新,则可以创建一个PHP脚本,该脚本将返回要执行的SQLite语句。 php脚本将从客户端获取最后更新序列/时间的参数。

如果您计划进行双向同步,那么您必须考虑合并和冲突解决方案。对于双向,每个方最好有一个事务队列。只需记录针对数据库执行的每个CRUD语句。同步时,应用这些语句,然后截断队列。

答案 4 :(得分:0)

SQuirreL SQL(在Java中使用Hibernate)有一个DBCopy插件。可以使用它编写数据库副本的脚本。我没有尝试过,但那是我要去的第一个方向。

答案 5 :(得分:0)

entropyDb具有自动复制功能,可以处理此