有没有办法告诉Core Data在所有实体都从基础实体继承时不将所有实体放入一个表中?这是一个例子:我们有一个“实体”对象,我们有一个继承自“实体”的“人物”和“产品”。核心数据创建一个ZENTITY表,其中包含“Entity”,“Person”和“Product”的组合字段。我们想要的是核心数据创建两个单独的表,一个用于“Person”,一个用于“Product”。
这甚至可能吗?网上没有任何关于此的内容......
答案 0 :(得分:13)
我做了测量,当在真实(~50000个对象,20多个类,每个有~5个关系,大多数对多数)数据上使用继承时,CoreData的性能完全降低。我没有将CD用于具有1000个对象的玩具应用程序 - 这是一个真正庞大的应用程序,性能压力是不合理的。更糟糕的是,由于这种愚蠢的实现,创建小对象需要大量的ssd和内存空间。
唯一真正的解决方案(我需要继承)是使用iOS 5及更高版本的NSIncrementalStore手动实现替换默认的sqlite持久存储。但是,对SQL转换和模型更新的获取请求实际上很难实现。
是的,我知道核心数据不是SQL。但我希望它在处理大量数据时能够以相对较快的速度运行 - 否则在现实世界的应用程序中使用它会很愚蠢。
答案 1 :(得分:10)
根据detailed article by Florian Kugler,解决方案是在模型代码中使用继承,但不在模式中使用:
实体层次结构与类层次结构
托管对象模型提供了创建实体的可能性 层次结构,即我们可以将实体指定为另一个实体的父节点 实体。这可能听起来不错,例如,如果我们的实体共享一些 共同属性。然而,在实践中,它很少是你想要的 想做。
幕后发生的事情是Core Data存储所有实体 在同一个表中使用相同的父实体。这很快就会产生 具有大量属性的表,会降低性能。 通常,创建实体层次结构的目的仅仅是创建 一个类层次结构,这样我们就可以将代码共享在多个之间 实体进入基类。有一个更好的方法来实现 这虽然。
实体层次结构独立于NSManagedObject子类 层次结构。换句话说,我们不需要有层次结构 在我们的实体中创建一个类层次结构。
https://www.objc.io/issues/4-core-data/core-data-models-and-model-objects/
答案 2 :(得分:3)
网上任何地方都没有谈论 这个..
那是因为表与Core Data无关。
核心数据不是SQL。实体不是表格。对象不是行。列不是属性。核心数据是一个对象图管理系统,可能会或可能不会持久保存对象图,并且可能会或可能不会使用远远落后的SQL来执行此操作。试图用SQL术语来思考核心数据将导致你完全误解核心数据并导致更多的悲伤和浪费时间。
在这种情况下,您的SQL训练直觉如何优化SQL将导致您浪费大量时间。如果您在开发时深入到SQLite存储中,则表示您正在错误地使用Core Data。它不仅仅是SQL的对象包装器。
当Core Data使用SQLite存储时,将所有具有相同继承的实体放入相同的SQL表中是一个设计决策。但是,在大多数情况下,作为核心数据,它几乎没有功能相关性首先管理对象图,并且很少关注持久性的细节。如果您拥有相同实体继承树的大量对象,则可能会在最高端遇到一些性能问题,例如: 20k +对象,但不是。
无论如何,都无法改变。 Core Data故意隐藏其SQL实现,因为SQL只是众多中的一个持久性选项。
过早优化是万恶之源。以逻辑上最好的方式构建然后测试。只有在测试中遇到边缘情况时,才应该担心SQL存储的细节。
答案 3 :(得分:2)
似乎这是一个老问题,但我仍然希望我可以帮助那些有同样问题的人。
我从这个网址找到了一个很好的答案: https://www.objc.io/issues/4-core-data/core-data-models-and-model-objects/#entity-hierarchy-vs-class-hierarchy
为了避免将来网址无效,我在此处发布了一些重要内容:
例如,我们有从BaseEntity继承的作者和书籍。 我们应该做的是设计实体应该是,而不是使用继承。
Entity hierarchy Class hierarchy
---------------- ---------------
Authors Books BaseEntity
| |
Authors Books
代码应该是这样的:
@interface BaseEntity : NSManagedObject
@property (nonatomic) int64_t identifier;
@property (nonatomic, strong) NSDate *createdAt;
@property (nonatomic, strong) NSDate *changedAt;
@end
@interface Author : BaseEntity
// Author specific code...
@end
@interface Book : BaseEntity
// Book specific code...
@end