【问题标题】:Core Data Performance with Single Parent Entity单父实体的核心数据性能
【发布时间】:2011-10-18 13:13:47
【问题描述】:

我正在创建一个适用于 Core Data 的框架。在您的 Core Data 类上使用我的框架的要求之一是,您希望拥有框架功能的任何实体都需要是我提供给您的实体的子实体和子类。为此,我将该对象称为 Foo。

今天我意识到 Core Data 将所有作为 Foo 子实体的对象存储到一个名为 ZFOO 的表中。如果拥有大量数据集的人想要使用 Core Data,我会担心它的性能,因为 foo 类的所有子实体都将存储在一个巨大的 ZFOO 表中。

任何意见或建议都将受到高度赞赏。

【问题讨论】:

  • 是的,如果您有大型数据集,CoreData 中的子类通常很糟糕,因为您最终可能会得到非常解析的表。但是,我的建议是先进行测试... 编写一个简单的应用程序,创建数千个您的类 Foo 的许多不同子类的对象,并查看系统的行为方式。如果它不明显,那么也许你没事。在对速度做出假设之前始终进行测试。
  • 感谢您的建议。我更多的是在寻找这种非常错误的恐怖故事。我读得越多,Apple 似乎就越鼓励 Core Data 中的这种继承。
  • 我可以确认它在 Xcode 5 DP5 中仍然这样做。
  • 我确认 Core Data 在 Xcode 7 iOS 9.2 中仍然可以做到,简直不敢相信。

标签: sql objective-c database sqlite core-data


【解决方案1】:

我作为 iOS 负责人与 @deathbob 合作过这个项目。在我们的实例中,我有多个包含属性“remote_id”和“remote_update”的类。我最初使用子类设置表。我有一个“RemoteEntity”抽象实体,其中包含这些属性和一堆从它继承的其他实体,每个实体都有自己的。我认为我们最终会得到一堆表,每个表都有remote_id、remote_update,然后是它们的自定义属性。相反,我们最终得到了您描述的那张巨大的桌子。

修复非常简单,您必须不通过 GUI 设置继承。而是在核心数据建模器中包含该对象的所有属性,包括您的共享属性(这意味着“remote_id”和“remote_update”将出现在每个实体中。话虽如此,我们仍然可以使用子类。生成模型的类后,创建父实体的类。这必须不在 GUI 中。它应该从 NSManagedObject 继承,并且在 .m 文件中,属性应该使用 @dynamic 而不是 @synthesize。现在你有了它的父类是时候调整子类了。将父类设置为 RemoteEntity(在我的示例中)而不是 NSManagedObject。然后删除出现在您的超类中的所有属性(在我的示例中为“remote_id”和“remote_update”)。

这是我的超类https://gist.github.com/1121689的一个例子。

我希望这会有所帮助,感谢@deathbob 指出这一点。

【讨论】:

  • 我遇到了同样的问题(单父实体,性能糟糕),想知道像您描述的那样的方法是否可行。您如何处理与父实体的关系?
  • 谢谢!它完美无缺!这样你在代码中有一个接口,在 BD 中有很多表(应该是这样)
  • 这听起来像是在解决一些也应该做的事情扔了 gui。那么它可能是一个错误比!?你仍然这样做还是从那以后做了一些改变?
  • 我今天试过了,但是你们如何在“RemoteEntity”实体上执行提取?
  • 这在我的特定情况下不起作用,但我很高兴听到它适用于某些人。听起来像一个奇怪的错误。
【解决方案2】:

去年我参与了一个做同样事情的项目,我们将所有内容存储在核心数据中,并将所有内容存储在从具有一些共同属性的单个类中继承的核心数据中。

我们在核心数据中有 1k 到 10k 条记录,性能下降到我们重写并删除共同祖先的地步。我记得简单的搜索需要几秒钟,插入/更新也很糟糕。只有在事情变得非常缓慢之后,我们才打开数据库并注意到核心数据在一张表中存储了所有内容。

抱歉,我不记得具体数字了,最大的收获是我们不得不重做它,因为它太慢了,而且不像高频交易太慢那样太慢,但太慢就像应用程序在尝试加载时崩溃一样从核心数据中填充初始视图。

因此,考虑到这在较旧的 iOS 和较旧的硬件上,我会说绝对不要这样做。

【讨论】:

  • Apple 在其高级 Core Data 视频之一中建议不要对 Core Data 中的实体进行子类化。
  • +1 感谢 Deathbob 和 @Christopher Bradford - 在我发现在开发应用程序的早期阶段发生这种情况后,你们都为我省去了很多麻烦!
  • 非常烦人的问题。我创建了一个托管对象的子类,并希望能够将它们放在单独的表中。当它们被一起提取时完全破坏了表视图!真的没有办法分开吗?
  • 这在 2020 年仍然有效吗?
【解决方案3】:

事后诸葛亮是一件很棒的事情。

由于人们仍在阅读此 Q&A 并在他们的问题中提及它并认为没有任何变化,因此我想添加一些 cmets 以清楚起见并提供“现代”或更近期的回应。

核心数据是一头强大的野兽,但你必须学会​​控制这头野兽,并且感谢之前回答的先驱者以及苹果对框架所做的改进,今天做起来比以前容易多了几年前(尤其是 iOS 5)。

最初,我建议学习如何准备可靠且稳健的数据模型。这方面的信息量很大,所以我将把它留给读者去研究。正如前面的答案所提到的,学习准备数据模型中的所有关系很重要。

除此之外,还有许多机制可以控制您获取的数据集的大小。 Marcus S. Zarra 的《Core Data, 2nd Edition, Data Storage and Management for iOS, OS X, and iCloud》(2013 年 1 月)一书中对我的解释最好不过了,尤其是 Marcus S. Zarra第 4 章标题为“性能调优”。

阅读。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多