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

时间:2013-01-18 09:46:00

标签: android database client-server offline-caching

这更像是一个概念问题,不一定与任何特定技术相关。 假设您在服务器上有一些数据库,一些REST / JSON API用于访问该数据库中的内容,一些移动客户端显示通过API检索的数据。

在客户端上有一些缓存机制并且只要客户端只读取就能够启用对数据的脱机访问会很好(在我的情况下,拒绝对脱机客户端的写访问权以避免必须管理可能发生的所有那些讨厌的冲突。

似乎解决这个问题的一个好方法是在客户端上提供服务器数据库模型的子集,并将数据从服务器同步到客户端。 然后,访问本地数据库可能会立即返回结果,但也会触发对服务器的更新请求。如果服务器返回修改后的数据,则客户端模型会同步其本地数据库并通知显示数据更改。

最终的目标当然是用户可以浏览信息而不管他的互联网连接的稳定性,并且只要他不修改任何数据,就不会被连接对话或类似的东西烦恼。

现在从实现的角度来看......一方面将服务器数据库直接耦合到客户端数据库似乎是一个坏主意,因为它们可能来自不同的供应商。我想至少在数据库实现之上需要一个独立于供应商的模型。另一方面,将数据从服务器数据库转换为某种传输格式,而不是将其放回到客户端数据库中,这似乎是一个很大的开销。

如何以优雅和可维护的方式解决这个问题?

2 个答案:

答案 0 :(得分:10)

我正在研发一款将大型数据库的小部分本地同步到手机上的应用程序。必须在手机上发生初始预加载,但之后更新在后台异步发生。

首先,强烈建议使用JSON或XML解耦服务器和手机。锁定为一种技术总是会导致问题,因为无论平台如何,您都被迫使用相同的技术。也就是说,如果您计划扩展到其他平台(Web,iOS等),您将被迫使用服务器指定的格式。从长远来看,选择通用格式会使这更简单。实际上,随着公共图书馆读/写数量的增加,JSON是一件小事。

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

<强> 1。 AlarmManager

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

<强> 2。 GCM

如果您只在更改时更新本地数据库,那么可以节省大量电池和数据。 Google Cloud Messaging可以向设备发送唤醒消息,并告诉它启动同步服务。同步服务的运行方式与上面的AlarmManager方法相同。

我们将上述两种方法结合起来,取决于您需要数据的“新鲜度”以及更改的频率。类似RSS提要的东西应该每30分钟更新一次,而天气数据可能不需要每4小时更新一次。

所以要运行我们使用的数据库同步;

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

更新UI

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

答案 1 :(得分:5)

我正在开发一个有类似要求的项目。我们希望在某个服务器上拥有一个可用的大型数据库,然后是从中获取数据的移动设备。如果设备离线,则可以,因为他们已在本地保存了自己的数据副本。

我们决定使用BigCouch(支持群集的Apache CouchDb的分支)作为服务器技术,然后使用移动设备上的Couchbase Mobile。 (注意到Android的TouchDB将取代Couchbase Mobile,但它还不稳定。)

我们使用Couch *技术的原因是Couch通过HTTP进行了良好的复制。您可以在移动设备上以编程方式启动同步事件,它将为您复制所有插入,更新和删除。它将信息存储在移动设备上的嵌入式CouchDb上,因此可以离线阅读。

如果您不想沿着Couch路走下去,您可以简单地使用类似SQLlite的东西来存储REST / API调用的结果。然后,您必须为移动设备脱机然后返回时编写自己的复制逻辑。有创造性的方法可以做到这一点,所以也许这是一个选择。