问题的简短形式:,从后续研究来看,我也许应该强调和简化我问题的核心。其核心是:其他用于Android的备份选项可能会导致恢复覆盖当前数据库中的数据的风险。是这样的吗?有没有一种没有这种风险的备份/恢复方法?
。
长形式的问题:在浏览了许多(相当多的)关于在Android上备份SQLite数据库的问题之后,有一个问题我找不到答案。
所有其他备份/还原讨论都涉及将db文件保存到SD (或者,在如何将安卓上的SQLite数据库备份/恢复到Dropbox中,保存到云中),然后在需要时恢复它。我担心的是,恢复不是覆盖当前DB吗?
我担心的是,当用户已经使用了很短时间的应用程序的新安装(生成新的数据),然后想从之前的应用程序备份中导入数据。使用所有其他备份/还原方法,似乎还原旧的DB文件将覆盖当前DB文件中的任何新数据。相反,我想要的是一个备份选项,在恢复时,可以将来自备份的数据添加到当前DB中,使其完成,而不覆盖其中的任何其他内容。
其他方法也是这样吗?或者,正如我所怀疑的,在这种情况下他们是否会被覆盖?
如果它们确实覆盖了,那么我最好的备份选项可能是将其写入csv或xml文件或其他什么东西,我希望这些备份讨论都是简单的方法。是否有任何进程构建来加速该进程并使其变得简单,或者我必须手动完成所有这些?如果是,建议写的格式和原因?
类似地,有没有人知道使用BackupAgentHelper内置的Google备份是否会有同样的覆盖问题?
最后,如果我在任何时候都经历了数据迁移(类似于核心数据模型改变后如何从备份中恢复SQLite数据库(轻量级迁移)),那么我现在应该做什么(我还在DB设计阶段),以使这样一个潜在的未来更改相对于这个备份过程更容易呢?
发布于 2016-02-10 23:39:49
我认为,在您描述的场景中,在不更改(或与“更新的”数据冲突)的情况下恢复旧数据的问题并不难解决。从本质上说,您只想将旧数据(记录)“添加”到新数据库中,前提是旧数据与新数据没有逻辑冲突(也就是说,为旧数据创建新记录在语义上是可以的)。我认为,在恢复过程中处理主要的关键冲突将是最重要的问题。
让我们拿两箱:
1:您正在使用数据库主键值特性的自动生成(例如,使用SQLite表的AUTOINCREMENT列)。
让我们假设“更新的”数据库记录可能在恢复过程开始之前使用了1到10的主键(ROWID)值。如果您的数据库记录中有任何一个主键值(1到10),那么只有当您想要保留这些旧的主键值时,才会出现问题。为了避免这个问题,不要保留“旧”记录的“旧”主键值--在从“旧”数据库读取记录后,只需保存“旧”记录的其他属性(列)的值,并让数据库为该“恢复”记录生成一个新的主键值。本质上,“旧”记录是用一个新的主键值保存的。如果您关心在这个“恢复”过程之后维护记录的时间顺序,我建议您也保留一个时间戳列,其值在过程中不会被更改。
2:您使用的是备用机制(UUID、序列生成器等)。用于生成主键值:
在这种情况下,读取“旧”记录,然后在“更新”数据库中保存它之前,将“旧”主键值替换为使用备用机制生成的主键值--通过设计,该机制将确保“还原”记录的主键值相对于先前存在的“更新”记录的唯一性。
为了简化这个“恢复”过程的编程工作,特别是在处理多个表时,您可以使用类似于JDXA的ORM。SDK附带的一个示例应用程序演示了一种类似的技术,用于在将数据库升级到更新版本的同时传输“旧”数据。JDXA还提供了一种方便的序列生成机制,可以轻松高效地创建唯一的ids,在持久化对象之前,可以将这些ids分配给对象。
发布于 2016-02-11 14:27:30
经过不断的研究,我越来越多地得出结论,没有更好的方法来解决这个问题。对于一个简单的备份,您可以简单地复制数据库文件,就像许多其他线程讨论并保留恢复问题上的覆盖一样(还有明显的兼容性问题:https://stackoverflow.com/a/10842043/3108762)。要进行真正健壮的备份,只需将整个DB写入XML,并将其与所需的所有工作一起读取。
我发现的唯一更好的选择是在https://stackoverflow.com/a/34477622/3108762中提到的,它指的是新的安卓功能为应用程序配置自动备份,但只适用于Android6.0或更高版本。我将对此进行测试,但如果它不起作用,而且对于Marshmallow以下的任何内容,似乎将我的整个DB写成XML,然后再次读取它是唯一真正健壮的方法。不完全是一个惊喜,但很高兴知道。
https://stackoverflow.com/questions/35227272
复制相似问题