CoreData - 在实体上有许多关系时的性能

Posted

技术标签:

【中文标题】CoreData - 在实体上有许多关系时的性能【英文标题】:CoreData - performance when having many relationships on an Entity 【发布时间】:2017-10-14 19:12:26 【问题描述】:

我希望以前没有人问过这个问题,我搜索了一个类似的问题,但找不到与我的情况足够接近的问题。

基本上,我的问题是 CoreData 是否可以处理大量关系(我的意思是在某些实体上可能多达 30 个),同时又不会太慢。

我有这些实体(仅作为演示):

Resources (contains all Resources for an object)
ProcessA
ProcessB
ProcessC
ProcessD
ProcessE
... (many more)

各种任务都需要这些流程,但几乎所有流程都需要与Resources 建立一对一(或一对多)关系。

有时,他们甚至需要与ResourcescurrentResourcesoldResources 或其他)建立多个关系。这就是为什么我需要添加一个逆关系(如果我没有逆关系,它实际上会导致问题。我不知道为什么)。

由于反转,Relationships 实体开始看起来像这样:

Resources
   someAttribute
   ...
   ---
-> inverseOfProcessA
-> inverseOfProcessB
-> inverseOfProcessC
-> inverseOfProcessD
-> inverseOfProcessE
-> ...

它充满了我永远不需要从这边访问的反向关系(它们只需要在那里防止一些奇怪的事情发生)。

我读懂了faulting 的概念。我的理解是否正确,当我获取 Resources 对象时,它实际上并没有加载所有关系?如果是这样,faulting 的效率如何?因为它确实必须用fault-objects 填充所有关系。那是我不太确定的部分。当实体上有许多关系时,这会影响性能吗?


如果这是一个微不足道的问题,我很抱歉。答案可能很明显,但我刚刚开始担心性能问题,这让我很感兴趣(尽管我在文档中读到了 faults,但这对我来说并不是 100% 清楚)

【问题讨论】:

【参考方案1】:

实际上,如果您问自己 Core Data 是否会在您的模型上遇到困难,您必须问自己您的选择是否正确。 我不知道 Core Data 是否可以处理这个问题,答案可能是肯定的,但这取决于其他各种因素:我们谈论的是几个条目还是数千个条目?有多少获取请求?

关于您的模型:为什么不创建单个实体 Process 以区分进程 A 和进程 B(标识符为整数或字符串)?

关于 faulting :默认情况下,当您创建 NSFetchRequest 时,returnsObjectsAsFaults 设置为 true 允许您使用大型数据集而无需具体化其中的所有对象记忆。如果您知道要访问所有关系,则可以将此属性设置为 false 以使用完全物化的对象,从而节省大量往返持久层的时间。

请记住,Core Data 只是一个关系数据库的包装器,因此请牢记这一点以优化您的模型和您的请求。

【讨论】:

我曾经这样做过(使用一个 Process 就像你说的那样)。它导致丑陋、复杂和难以维护的代码(在我的例子中,没有更漂亮的方法)。此外,每个进程都需要有不同类型的属性和关系(例如,ProcessA 需要保存 3 个字符串和一个浮点数,而 ProcessB 需要 3 个整数和一个日期)。我需要有许多“通用”属性(如string1string2integer1、...),这些属性也很难使用。我有一个解决方法,但这更难看。 这就是我切换到单一用途实体的原因,这会产生非常清晰且易于维护的代码并且更容易使用。有人告诉我,对于某事始终只有一个目的通常是个好主意。 我理解你的问题,但你必须找到一个解决方法,因为即使你持有一个 Resource 对象,你怎么知道哪个关系指向正确的 Process ?尝试添加其他实体以将您的模型分解为其他部分或使用父实体。 这就是重点,我不需要知道这个。我永远不需要从 Resource 对象一侧访问关系。

以上是关于CoreData - 在实体上有许多关系时的性能的主要内容,如果未能解决你的问题,请参考以下文章

如何对 CoreData 中的许多关系执行复合查询

CoreData 和许多 NSArrayController

在 Core Data 中加载具有关系的托管对象时的标准行为是啥?

在 CoreData 中更新和编辑实体

在CoreData ios 10的实体内添加一个属性

使用 CoreData 关系计算摘要