我用sqlite3.在xcode中创建了一个应用程序。我想创建一个名为sync的按钮,以便与我服务器中的mysql数据库同步。有关同步过程的任何建议吗?请告诉我。
答案 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具有自动复制功能,可以处理此