从服务器到客户端同步部分数据库模型

14
这更多是一个概念性的问题,不一定局限于任何特定的技术。 假设你在服务器上有一些数据库、一些REST/JSON API来访问该数据库中的内容以及一些通过API检索到的数据的移动客户端。
客户端上进行缓存并能够启用离线访问数据是很好的,只要客户端仅仅是读取(在我的情况下,拒绝脱机客户端的写入访问是可以的,以避免管理所有可能发生的麻烦冲突)。
解决这个问题的一个好方法似乎是在客户端上有服务器数据库模型的子集,并将数据从服务器同步到客户端。然后访问本地数据库可能会立即返回结果,但也会触发对服务器的更新请求。如果服务器返回已修改的数据,则客户端模型将同步其本地数据库并通知数据更改的显示。
最终的目标当然是让用户能够浏览信息,而不管他的互联网连接稳定与否,并且只要他不修改任何数据,就不会被连接对话框或类似的东西所干扰。
现在从实现的角度来看...一方面,直接将服务器数据库耦合到客户端数据库似乎是一个坏主意,因为它们可能来自不同的供应商。我想,至少需要在两个数据库实现之上有一个供应商无关的模型。另一方面,将数据从服务器数据库转换为某些传输格式,然后将其放回客户端数据库似乎需要很多开销。
有什么建议以优雅和可维护的方式解决这个问题吗?
2个回答

10

我正在开发一个应用程序,将大型数据库的小部分同步到手机本地。在手机上需要进行初始预加载,但之后的更新将在后台异步进行。

首先,建议使用JSON或XML来解耦服务器和手持设备。锁定一种技术总会导致问题,因为你不得不无论平台如何都要使用相同的技术。也就是说,如果你计划扩展到其他平台(Web、iOS等),你必须使用服务器指定的格式。选择通用格式将使长期来看更加简单。实际上,由于有大量公共库可供使用,读写JSON是一个微不足道的事情。

我们使用两种方式同步数据;

1. AlarmManager

我们将AlarmManager安排在定期时间内触发服务(假设每6小时)。唤醒启动一个后台服务,联系服务器,下载JSON中的更改并更新本地SQLite DB。如果没有连接,则跳过更新并安排下一个唤醒。我们添加了一个ConnectivityChanged接收器,以便在恢复连接时自动重新启动同步。

2. GCM

它需要更多工作,但如果只在有更改时更新本地数据库,则可以节省大量电池和数据使用。Google Cloud Messaging可以向设备发送唤醒消息,并告诉它启动同步服务。同步服务与AlarmManager方法相同。

我们根据需要数据的“新鲜度”以及更改频率使用上述两种方法的组合。像RSS订阅之类的东西可能应该每30分钟更新一次,而天气数据可能不需要每4小时更新一次。

因此,为了运行数据库同步,我们使用以下内容;

接收器 -> 监听系统事件并触发服务 服务 -> 连接服务器,下载JSON并更新SQLite提供程序 提供程序 -> 将记录插入数据库并向ContentObservers广播内容更改 ContentObservers -> 当应用程序运行时,ContentObservers将使用新数据更新UI

以上每个组件中都涉及很多技术细节,但这应该为您提供了一个非常强大的架构,用于将服务器数据与本地数据库同步。


我强烈建议采用John上述的两个选项之一。由于GCM已经内置在Android中,因此它更受青睐。但是,如果您的项目需求无法满足GCM路线,则仍可选择第一个选项。 - Bogdan Zurac
我不喜欢第一个选项,因为这可能会导致更新用户可能永远不会查看的数据。对于轻量级通知,我计划包括GCM,但通过它触发数据库更新可能在我的情况下太浪费了。而且,我不确定它在移动电话平台上的效果如何,因为这些推送服务似乎相当特定于供应商。你对第三个选项有什么想法?根据使用情况更新本地数据库。当本地访问数据时,可能会立即返回本地结果,但也会为相同的数据发送一个到服务器的请求。 - mibollma

5
我正在处理一个类似的项目。我们想要在某个服务器上拥有一个可用的大型数据库,然后从移动设备获取数据。如果设备离线了,因为它们已经在本地保存了数据的副本,所以没有问题。
我们决定使用BigCouch(Apache CouchDb的分支,支持集群)作为服务器技术,然后在移动设备上使用Couchbase Mobile。(作为注释,TouchDB for Android将取代Couchbase Mobile,但目前还不稳定。)
我们选择Couch* 技术的原因是Couch在HTTP上具有良好的复制功能。您可以在移动设备上编程启动同步事件,它会为您复制所有插入、更新和删除操作。它将信息存储在移动设备上自己的嵌入式CouchDb中,因此可以在离线状态下读取。
如果您不想使用CouchDb这条路,您可以简单地使用SQLlite来存储REST/API调用的结果。然后,当移动设备离线并重新连接时,您将不得不编写自己的复制逻辑。有创造性的方法来解决这个问题,因此也许这是一个选择。

你所说的Couchbase Mobile是指Github上的Android-Couchbase,而TouchDB是指Github上的TouchDB-Android吗?我只是想知道这两个项目都已经有一段时间没有更新了,这让我怀疑它们是否适合在生产环境中使用。 - mibollma
1
是的,我的意思就是这两个。你说的对,这两个项目都已经相当死了。事实上,Couchbase Mobile已经正式宣告死亡了。TouchDB是iOS版本的移植版(非常稳定,而且还有很多人在维护),但它并不完整。目前我们选择使用Couchbase Mobile来进行Android开发。虽然代码已经停止更新,但还能够工作。我们希望Couch团队现在可以有时间专注于TouchDB 的移植,因为Couchbase 2.0已经发布了。这实际上是一个计算风险,这样我们就不必从头开始编写复制功能。 - ryan1234

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接