更新本地Android数据库

时间:2014-09-22 07:50:37

标签: android database sqlite

我目前在Android上遇到SQLite数据库问题。

我的应用程序在apk文件中有一个本地数据库。当应用程序启动时,它将检查新版本,并下载全新的数据库(如果可用)(尽管在两个数据库版本之间,更改很少)。但是现在数据库太大了。因此,新数据库可用时需要很长时间。那么解决这个问题的方法呢?

8 个答案:

答案 0 :(得分:5)

基本理念

我是这样做的。我假设客户端应用程序不对本地数据库进行更改(除非下载新版本),因此只存在少数可能的数据库版本(每次都有一个版本)在服务器端进行了更改)。

  1. 为名为LastModified的每个表添加一列,默认值为NOW()。这意味着每次向主副本添加内容时,都会获得更新的LastModified设置。您必须确保更新(而不是插入)也会更改LastModified字段。
  2. 在数据库(Settings表或某物)中的某个位置存储一个字段,该字段用于跟踪此版本数据库在服务器上发布的日期(称之为PublishDate)。
  3. 当客户端想要检查新版本时,它会将PublishDate发送到服务器。然后,服务器检查每个表,并找到LastModified之后PublishDate所在的每一行。它将SQL发送到客户端以在客户端上插入或更新这些行。它还会发送新的PublishDate,以便客户端可以在其本地副本中更新它。
  4. 这涉及插入和更新。它不处理删除。在你的情况下,它们可能不是问题;如果他们是:

    1. 添加一个单独的表来记录删除,您还可以在其中跟踪LastModified,以便您可以告诉客户端要删除哪些行;或者最好有一个设置,你实际上没有删除任何行,但只是更新它们以标记为“已删除”。
    2. 最后,这不会处理架构更改。再次,希望这不是你的问题:希望你有一个稳定的架构。但是,如果您确实需要添加或删除表或索引或其他内容,则必须单独完成:

      1. 在您的主人上创建一个SchemaChanges表格,每当您进行结构更改时,请将相关详细信息放入SchemaChanges表格,并附上LastModified日期,以便您可以发送这也是客户要求的。如果您这样做,您将首先要将架构更改发送到客户端,因为它们可能会影响其他更改的含义。
      2. 现在这样做的好处是你可以预先处理服务器上的所有内容(因为现有的版本只有几个版本)。对于每个旧版本,您可以计算将旧版本更新到新版本的更改(基于上面的详细信息),然后将生成的SQL存储在服务器上。如果这样做,则无需动态生成SQL:当客户端发送PublishDate时,您只需查找已经计算过的SQL,即从PublishDate转换版本到最新版本。

        替代实施

        有一种很好的简单方法可以推动上述方案为您提供的更改,即使只需要LastModified次的轻微简化,或者对现有结构进行任何更改。在服务器端,您已经拥有旧版本(因为您拥有所有旧版本)和新版本,您可以创建两个数据库的SQL转储,然后对它们运行diff以生成补丁文件您可以发送到客户端应用程序。客户端应用程序将使用相同的Java库生成旧版本的SQL转储,然后将diff补丁应用于它以为新版本创建完整的SQL转储。此时,它可以删除旧数据库并从SQL转储中创建新数据库。

        如果更改不是批量更改,这将非常有效(在这种情况下,您可能只需按下新的.db文件)。

        通过invoking the SQLite binary创建转储相当容易。根据执行外部命令的this way,您需要稍微修改Android的方法。

        您可以使用this Google library计算服务器端的差异补丁并在客户端应用它们。

答案 1 :(得分:4)

获取更改,而不是获取整个新数据库文件。更改可能采用SQL脚本的形式。让服务器为每次更新生成更改脚本,然后您可以下载SQL脚本并按顺序在本地数据库上运行它们。

答案 2 :(得分:3)

您需要为服务器上的数据库所做的任何更改创建时间戳。

当应用程序连接到您的服务器时,它会发送下载的最后一个时间戳,以便您的服务器知道要下载的新数据是什么。

设备上没有根据实时设置时间戳,您需要下载它以避免时区问题是不同的小时值。

如果您愿意,可以使用连续数字版本而不是时间戳

答案 3 :(得分:3)

我一直在研究类似的问题,每次服务器上有任何更改时我都必须更新本地数据库。诀窍是跟踪android中本地数据库中的上次更新时间,并发送该时间以获得JSON格式的服务器更新。在这里,您必须编写服务器端代码,将输入作为上次更新时间,并以JSON格式返回对服务器端数据库所做的所有更新。

获取JSON数据后,您必须将JSON数据转换为SQL查询并在本地数据库中插入或更新。

看看this回答。另请参阅Google IO 2014代码here

我最终将ContentProvider与架构和合同类一起使用,如here所述。

然后我为数据库中的每个表创建了java对象,并使用gson library将传入的JSON更新转换为java对象。之后,您必须编写documentation中给出的inser / update / delete查询。

基本上,您必须为数据库处理创建合同,数据库和提供程序类。对于数据库中的每个表,java类都有一个,您可以编写代码从服务器获取JSON更新,将JSON字符串转换为java对象,然后在数据库中插入/更新/删除。演示代码可在Google IO 2014应用中找到。

答案 4 :(得分:3)

你的问题中不清楚的是你是否想要

  1. 双向同步(客户端和服务器可以进行数据更改)或仅
  2. 单向同步(只有服务器或客户端才能进行更改)。
  3. 对我来说,这听起来更像是你想要从服务器到客户端的单向同步。这正是Google I / O对会议数据所做的工作。你可以在这里找到一个详细的博客文章如何工作:
    Conference Data Sync and GCM in the Google I/O App,请查看“有效下载会议数据”一章,该章涉及manifest.jsonsessions.jsonspeakers.json。如果数据模式发生变化,只需提供一个新的应用程序,它以标准的android方式执行模式更改,并以忽略其他字段的方式使您的json解析例程。就像补充一样:

    如果您想要双向同步,那么chiastic-security可以很好地概述数据库操作。缺少的是解决方案的编程方式:

    希望有所帮助。

答案 5 :(得分:2)

使用greenDao,您可以在此处执行此类迁移Check。祝好运。

答案 6 :(得分:1)

您可以通过Google Cloud Messaging API执行此操作。这是Google为开发人员提供的功能,适用于Android和IOS设备。 Google Cloud Messaging(GCM)是一项服务,可帮助开发人员在在线服务器和应用之间发送数据。使用此服务,您可以在新数据可用时将数据发送到您的应用程序,而不是及时向服务器发出新请求。

使用GCM的一个很棒的教程是this

希望有所帮助:)

答案 7 :(得分:1)

也许您可以使用服务来更改数据库版本。因此用户无法注意到并且用户继续使用该应用程序。服务完成后,应用程序发送通知。当然只有合作和建议。