防止核心数据合并为一个表
有没有办法告诉核心数据不把所有的实体放在一个表中,当他们都从基础实体inheritance? 下面是一个例子:我们有一个“实体”对象,我们有一个从“实体”inheritance的“人”和“产品”。 核心数据创build一个“实体”,“人”和“产品”组合字段的ZENTITY表。 我们想要的是核心数据创build两个单独的表,一个用于“Person”,一个用于“Product”。
这甚至有可能吗? 网上没有任何网上谈到这个…
我做了测量,CoreData的性能在真实(〜50000个对象,20多个类,每个具有〜5个关系,其中大部分是多对一)数据的情况下使用inheritance时完全降级。 我不把CD用于1000个对象的玩具应用 – 这是一个真正的巨大的应用程序和性能的处罚是不合理的。 更糟的是,创build小对象需要大量的ssd和内存空间,因为这个愚蠢的实现。
唯一真正的解决scheme(我需要inheritance)是用iOS 5或更高版本的NSIncrementalStore手动实现来replace默认的sqlite持久存储库。 但是,对SQL转换和模型更新的获取请求确实很难实现。
是的,我知道核心数据不是一个SQL。 但是,我期望在处理大量数据时它的工作速度相当快,否则在现实世界的应用程序中使用它会是愚蠢的。
根据Florian Kugler撰写的详细文章 ,解决scheme是在模型代码中使用inheritance,但不在模式中使用inheritance:
实体层次与类层次
托pipe对象模型提供了创build实体层次结构的可能性,即我们可以指定一个实体作为另一个实体的父项。 例如,如果我们的实体共享一些共同的属性,这听起来很不错。 然而在实践中,很less有你想做的事情。
核心数据在后台发生的事情是将具有相同父实体的所有实体存储在同一个表中。 这很快就会创build具有大量属性的表格,从而降低性能。 通常创build实体层次结构的目的仅仅是创build一个类层次结构,以便我们可以将多个实体之间的代码共享到基类中。 有一个更好的方法来实现这一点,虽然。
实体层次结构独立于NSManagedObject子类层次结构。 换句话说,我们不需要在我们的实体中有一个层次结构来创build一个类层次结构。
https://www.objc.io/issues/4-core-data/core-data-models-and-model-objects/
看来这是个老问题,但我仍然希望能帮助有同样问题的人。
我从这个URLfind了一个很好的答案: https : //www.objc.io/issues/4-core-data/core-data-models-and-model-objects/#entity-hierarchy-vs-class-hierarchy 。
为了避免将来URL变得无效,我在这里发布了一些重要的内容:
例如,我们有从BaseEntityinheritance的作者和书籍。 我们应该做的是devise实体,而不是使用inheritance。
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
没有任何地方在线谈论这个..
这是因为表与Core Data无关。
核心数据不是SQL。 实体不是表格。 对象不是行。 列不是属性。 核心数据是一个对象图pipe理系统,可能会或可能不会坚持对象图,可能会或可能不会在后台使用SQL来做到这一点。 试图用SQL语言来思考核心数据会导致你完全误解核心数据,并导致很多的悲伤和浪费时间。
在这种情况下,您的SQL训练直觉如何优化SQL将导致您浪费了大量时间。 如果您在开发时进入SQLite存储库,则说明您正在使用Core Data。 这不仅仅是SQL的对象包装器。
当Core Data使用SQLite存储时 ,将所有具有相同inheritance的实体放入同一个SQL表是一个devise决定。 然而,在大多数情况下,核心数据首先pipe理对象图,而对持久性的细节却很less关注。 如果你有大量的相同的实体inheritance树的对象,你可能会遇到一些性能问题,例如20k +对象,但不是。
无论如何,这是不能改变的。 核心数据故意隐藏其SQL实现,因为SQL只是一个持久性选项。
不成熟的优化是万恶之源。 build立在逻辑上最好的时尚,然后testing。 只有在testing中遇到边缘情况时,才应该担心SQL存储的细节。