【发布时间】:2011-02-15 21:01:13
【问题描述】:
我们的主服务器 (PHP/MySQL) 上有一个数据库,用于存储通过网站更新的数据。我试图找出将这些数据复制到本地 SQLite 数据库(在 android 上运行)的最佳方法。由于移动互联网速度等的限制,我需要建立检查以查看每一行是否需要更新。认为每一行的版本号可能是最好的解决方案。
人们对此有何看法?
谢谢, 内森
【问题讨论】:
我们的主服务器 (PHP/MySQL) 上有一个数据库,用于存储通过网站更新的数据。我试图找出将这些数据复制到本地 SQLite 数据库(在 android 上运行)的最佳方法。由于移动互联网速度等的限制,我需要建立检查以查看每一行是否需要更新。认为每一行的版本号可能是最好的解决方案。
人们对此有何看法?
谢谢, 内森
【问题讨论】:
使用时间戳不是更容易吗?只需获取自特定时间以来更新的所有行。您需要复制多少数据?
【讨论】:
根据数据库的大小,binary search 可能是值得的。
基本上,想出一个在行子集上运行MD5() 的查询。然后就像以二进制方式沿着树向下走一样简单,跳过那些匹配的部分。步骤:
预先计算搜索的前 3 级(左右),将其发送给客户端。
在客户端,计算这 3 个级别,检查匹配项。在不匹配的那些上,计算 3 个级别(每个不匹配的级别 14 个哈希)并发送回服务器。
在服务器上,计算接下来的 3 个级别并与客户端发送的内容进行比较。计算不匹配行的下 3 个级别。
重复 2-3 直到每个限制中的行数达到 1。在那里,您已经确定了差异,因此从服务器发送/请求它们,您就完成了。
现在,为什么这比发送转储更有效?好吧,对于 1 行更改,大约需要 log(total_rows, 2) * (sizeofMD5 + 2) 字节传输(不包括开销)。因此,对于一个 100 万行的表,大约需要 352 字节的反向数据来确定更改的行。现在,更改的行越多,它将使用的数据越多。
我选择了 3 个批次,因为这是在处理额外数据和减少连接数量的延迟之间的良好折衷。
现在,就哈希行而言,您可以执行以下操作:
SELECT MD5(GROUP_CONCAT(row)) AS checksum FROM
(
SELECT 1 AS grouping, MD5(CONCAT(id, col2, col3)) AS row
FROM table
ORDER BY id ASC
WHERE id > ? AND id < ?
) AS a
GROUP BY grouping
这将产生一个 MD5,该 MD5 取决于限制中的每一行。 (还有其他方法,但这只是一个例子)。然后用0, count(rows) 调用它来检查整个表,然后从那里向下迭代链。
请注意,这仅适用于具有整数 PK 的表(因为它被用作二进制搜索的边界窗口)。但它会以相同的速度、效率和代码检测每种类型的更改(master-delete、slave-delete、master-change、slave-change、master-insert、slave-insert)。
【讨论】: