好吧,您意识到这是一个不小的问题。去年,我为一个商业应用程序编写了一个库来完成此任务,花了大约 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)
正如我所说,这并非微不足道。我将很快提供这个库。如果您想查看,请给我发电子邮件。
编写完通信后,您就可以开始设计同步。我要么对每个记录使用哈希值,要么使用简单的布尔标志。如果服务器上有任何更改,只需发送整个记录并在客户端覆盖它(假设您试图保持客户端同步......)
如果您自己写,请在这里回复您的经验!
附言。考虑更改标题以使其更易于搜索。也许类似:
“同步 SQLite 客户端数据库与 MySQL 服务器数据库”