6

这个问题是关于我认为在 Android / iOS 开发中非常常见的问题,但我还没有找到任何“标准”解决方案。

假设我们有一个相当普通的 REST API。服务器数据库包含(除其他外)表countriestowns具有 1:N 关系。

客户端(移动应用程序)想要维护这两个表的本地快照。这样当它离线时,它可以执行通常通过 REST 完成的查询,例如:“获取人口 >= 100 的奥地利城镇列表”?

如何解决这个问题?

第一个问题:一致性。客户端应该有两个表的快照。如果客户端下载towns表的更新并离线,则某些城镇可能会引用不在countries表的本地副本中的国家/地区。

第二个问题:客户端应该只下载新的/删除的/更改的行。放弃 REST 并使用一些自定义 RPC 调用,例如get_updates_since(...)

第三个问题:客户端对数据库副本的本地更改(可能离线)应该如何与服务器同步?自定义 RPC 调用?

4

2 回答 2

6

我认为没有灵丹妙药,但您正在寻找的模式是缓存。在过去的项目中,我将项目从服务器复制到本地存储(SQLite 或平面文件),并根据简单规则维护有关要更新/上传/清除的条目的元数据。这不是一个简单的问题,最终会变成很多代码。

一致性:在您的示例中,要么确保首先下载国家/地区表,要么使这两个操作原子化-例如,制作“新”表的副本,并且仅在两个副本都成功完成时才替换缓存的版本(存储空间翻倍)。

只下载新的/删除的/更改的:是的,这需要客户端/服务器集成 - 为所有记录添加时间戳(使用 GMT),从服务器请求元数据,并通过本地元数据来决定要做什么。(行上的提示 UUID 很有帮助)。

同步本地更改:是的,更多的客户端/服务器集成。见上段。

处理所有异常和边缘情况具有挑战性。看看iCloud 同步 CoreData 的问题。也许不是一个公平的比较,因为 Apple 正试图为一个完全分布式的数据库解决这个问题,但读起来还是很有趣。

于 2013-09-11T21:05:27.703 回答
5

目前,我正在处理相同的任务 - 构建 Android 应用程序,该应用程序将使用Azure 移动服务与中央 SQL 数据库同步信息。同步策略是支持来自多个客户端的双向同步,以确保数据一致性,而只会交换增量更改。

让我为您的问题提供我的解决方案。我最近写了一篇关于同步算法的博客文章来支持这种情况。

由于 REST API 通信,同步逻辑将在客户端进行管理。参与同步过程的每个表都将具有用于 CRUD 操作的相应 REST Api 方法。

对于您的第一个问题(一致性)——解决方案是以正确的顺序在客户端下载数据。例如,首先是父母,然后是孩子,以避免参照完整性问题。如果出现网络问题,客户端将不得不再次同步以获取其余数据。

第二个问题(仅下载增量更改) - 解决方案是时间戳(正如凯文在下面的回答中提到的那样)。但我建议使用在服务器端维护的全局递增值,以避免客户端和服务器之间的时间戳差异问题。SQL Server 的 rowversion 非常适合这一点。

第三个问题(来自客户端的数据集成)——在客户端表中使用 Dirty 标志将有助于区分上传所需的记录。

您可能还需要在两侧引入 Delete 标志来处理多个客户端之间的删除。

于 2013-09-12T11:52:11.593 回答