核心数据迁移无需将所有数据读入内存?

时间:2014-04-30 17:55:00

标签: ios objective-c sqlite core-data

我们有一个核心数据DB(sqlite商店),对于某些用户来说,大约100-150 MB。我不认为这对于存储系统来说太大了(即使在移动设备上),但我们发现使用那么大的核心数据DB,任何轻量级迁移都需要大约10 +秒才能完成。甚至像添加一个全新的独立实体(与任何其他实体无关)一样简单。使用原始sqlite,这将是一个create table语句。所以,我的问题是,是否有其他人已经看到了这一点,如果有的话,他们是否找到了解决方法来更快地进行这种简单的迁移?具体来说,我正在寻找一种方法来处理一个新的独立实体添加到现有的核心数据DB,大约100-150 MB并且速度很快(即5秒以下)。

我认为核心数据迁移总是必须从源读取所有数据并将其全部写入目标以进行迁移(这是可怕的BTW),但我希望有人可以证明我错了。 :)我无法通过自定义迁移找到任何方法。

我已经考虑过直接使用sql来修改数据库,基本上使模型看起来像CoreData所期望的那样(我已经做过这样的事情来手动“降级”核心数据DB以进行调试)但是我们真的想要避免在生产中做类似的事情。

更新

作为参考,这是我们目前正在采取的方法。这不是通用解决方案,但适用于我们的用例。除非我得到更好的答案,否则我将在未来的某个时候将其作为答案添加并接受它。

我们将通过实质上使数据库更小来解决这个问题。 15个实体中有2个占据了DB中的大部分空间(~95%)。我们将创建完全独立的数据模型,每个模型都有一个这样的实体。这样做完全没有改变主模型(因此,没有核心数据迁移)。然后,我们将在GCD中创建一个以后台优先级运行的任务,如果在主DB中找到任何这些实体,它们将被移动到相应的单独DB并从主DB中删除。这是批量完成的,批次之间有一些睡眠,因此资源消耗较少,不会影响正常的应用程序操作。我们将修改访问这些实体的代码,以尝试从新数据库中获取它们,如果它们不在那里,则回退到主数据库。

在我们发现所有或至少大多数用户在新数据库中更新了他们的数据之后的未来更新中,我们将从主数据库中删除这些实体。

这给我们留下了一个可以快速应用迁移的小型主数据库,以及两个迁移速度较慢的大型数据库。在我们的例子中,那些大型DB应该不经常更改(可能永远不会?),即使它们确实发生了变化,应用程序中有限的位置需要它们,因此我们可以在UI中解决它(例如,将某些功能报告为不可用直到我们移动数据。)

1 个答案:

答案 0 :(得分:2)

更新大数据集的10-20秒延迟似乎对我来说非常合理。只是不要在主线程上这样做。

这意味着您必须修改通常的Xcode模板中的样板核心数据堆栈设置。而不是总是在启动时在主线程上设置堆栈,检查是否需要迁移。如果是这样,请建立适当的UI,在后台线程中进行迁移,并准备好在需要时调用beginBackgroundTaskWithExpirationHandler: