繁体   English   中英

将SQLite3数据库与iCloud同步

[英]Sync SQLite3 database with iCloud

之前曾多次问过这个问题,但我一直找不到完整的答案。 我需要使用sqlite3数据库将数据存储在我的应用程序中,而核心数据不是一种选择。 我想使用iCloud在设备之间同步数据,最好的方法似乎是将SQL事务日志发送到iCloud并使用它们使设备保持最新。 到目前为止,我想出的过程如下:

  • 一旦执行,所有数据库更改查询(INSERT,UPDATE,DELETE)都存储在事务数组中,该数组的每个元素包含sql查询和执行该查询的时间戳。
  • 该数据库包含一个表,用于记录应用程序最后到达的事务数组中的点(包括存储在iCloud上的事务文件的文件名)
  • 交易数组已保存到iCloud上的设备唯一文件
  • 同步时:
    1. 从iCloud获取交易文件数组
    2. 创建要提交的空交易数组
    3. 对于每个文件:
      • 检查数据库以获取事务文件中的最后位置
      • 如果没有,则从文件开头开始
      • 从该点将每个事务添加到要提交的事务数组中
      • 使用事务文件的新最后位置更新数据库,因此不会重复同步的事务
    4. 按事务时间戳对要提交的事务数组进行排序
    5. 执行要提交的事务数组中的命令

我相信我可以通过将数据下拉到每个设备并执行更新每个本地副本的命令来完成此工作。 我设想的唯一问题是,当两个设备都脱机时将其插入到同一表中,然后进行同步。 例如:

  1. 设备1和设备2都有数据库的同步副本,表“ table1”中各有四个记录
  2. 设备1使用PK 5将值“ foo”插入表“ table1”
  3. 设备2使用PK 5将值“ bar”插入表“ table1”
  4. 设备1下载设备2的事务日志,并将值“ bar”插入ID 6
  5. 设备2下载设备1的事务日志,并将值“ foo”插入ID 6

现在,我们遇到一种情况,这些记录的主键在每个设备上都被反转了,这将中断到依赖于主键进行链接的表的链接。

我仍在尝试解决此问题的方法,但与此同时,如果有人提出建议,我将非常感谢!

我整天都在考虑这个问题,并且我想出了一个解决方案。 我将其发布在这里,以查看是否有人有任何评论,明天我将着手实现它。

我的想法是取消自动递增的整数主键,然后将其替换为基于字符串的键。 密钥将根据设备的UUID和时间戳生成。 这意味着密钥是设备特定的,行是唯一的。 因此,使用这种方法从上面重新说明INSERT示例(使用简化的字符串方便阅读):

  1. 设备1和设备2都有数据库的同步副本,表“ table1”中各有四个记录
  2. 设备1将值“ foo”插入到带有PK“ abc123”的表“ table1”中
  3. 设备2将值“ bar”插入到具有PK“ def456”的表“ table1”中
  4. 设备1下载设备2的事务日志,并将值“ bar”插入ID“ def456”
  5. 设备2下载设备1的事务日志,并将值“ foo”插入ID“ abc123”

之所以可行,是因为设备知道事务将导致插入使用设备特定值进行键控的行。 因此,在插入操作之后,键列中没有重复值的危险。

欢迎对此方法有任何想法!

更新我正在将其标记为正确的答案,因为它起作用了。 这是我修改现有数据库(和应用程序)以允许跨设备同步的方式。 幸运的是,这还不是生产应用程序,因此所需的数据库重大更改没有引起问题。

  1. 更改所有数据库表以使用TEXT类型列作为其主键
  2. 向数据库添加一个“最后一个索引”表,该表以表名作为关键字,并具有另一列以显示添加到该表的最后一行的索引号
  3. 向应用程序添加了一种方法,该方法通过检索表的最后插入索引并将其递增一个,然后将其的设备的UUID添加到该表中,从而生成设备和行唯一的TEXT密钥。
  4. 当插入任何行时,将调用(3)中描述的方法以获得将记录插入数据库的适当键。
  5. 所有数据库修改功能都会导致将SQL查询添加到事务日志中,并且该事务的每个条目都带有日期和时间戳,并使用设备的UUID作为文件名保存到本地文件中
  6. 然后将设备的本地事务日志上推到iCloud
  7. 同步涉及以下内容:
    • 从iCloud下载所有交易日志
    • 忽略设备自己的事务日志,遍历每个日志中的SQL命令列表,并将它们添加到命令数组中,从最后一次同步时该日志的完成索引号开始
    • 将完成日志的索引号存储在数据库中,以便在下一次同步时不会重新执行相同的命令
    • 按日期对所有日志中所有SQL命令的数组进行排序
    • 按顺序执行命令

关于该过程的实施,我到了第5步。到目前为止,还没有实施iCloud特定的东西。 但是,我已经通过在运行该应用程序副本的设备之间手动复制事务日志来测试了该过程,并且可以确认该过程可以正常工作。 包含设备UUID的TEXT主键可确保不会发生冲突。 所有设备都可以插入彼此的数据,并且密钥始终是唯一的。

这样做的缺点是数据库将更大(因为键长于整数),并且由于涉及大量字符串比较,因此查询可能需要更长的时间。 但是,我使用的数据库相对较小,并且每个用户交互只有几个查询,因此在这里我不会遇到问题。

我希望这对其他遇到相同问题的人有用:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM