减少 Core Data 中的关系数量

Posted

技术标签:

【中文标题】减少 Core Data 中的关系数量【英文标题】:Reducing number of relationships in Core Data 【发布时间】:2018-11-17 20:20:06 【问题描述】:

我的应用附带在 Core Data 中创建的广泛数据模型。随着模型的增长,我发现我正在创建大量的可选关系,而且它看起来比我认为的更凌乱和臃肿。 是否有适当的方法来减少关系数量?

一般来说,众多关系的主要驱动因素是我有许多需要某些特定属性的实体,具体取决于实体的形态。我画了一个假设的例子来创建一些上下文。想象在应用程序中用户可以创建动物。每一种动物都有一些一般属性,但根据我们所处理的动物,也有一些特定的属性。 我目前的方法将导致一个模型,其中动物实体与指定的属性实体具有多个一对一的关系,如下面的模型所示。

但是,很明显,当您想要扩展此模型时,关系的数量很容易失控。此外,没有什么可以阻止当前动物错误地分配多个指定的属性实体。 我正在考虑改用另一种方法,即删除核心数据关系并使用 UID 将动物与特定属性相匹配,如下图所示。动物实体获得一个“specifiedProps”属性,我在其中存储了一个 UID,该 UID 链接到一个指定属性实体,每个实体都获得一个 UID 属性。

据我所知,这有以下缺点和好处

缺点:

它需要一些通常由 Core Data 处理的开销(如级联删除), 获取速度会慢一些,但每只动物只需要获取一个指定的属性实体,所以我认为这应该不是问题。

好处:

随着用户创建越来越多的动物,减少我的应用中不断增长的可选关系数量并节省存储空间。 一种动物显然只有一个特定的属性。 更容易迁移;引入新动物时,无需创建任何关系,只需创建一个新实体即可。

我的问题是我是否忽略了什么?我是否犯了一个严重的错误,或者,也许有更好的选择?

任何评论批评将不胜感激。

附言。我知道 Core Data 允许父/子实体,但据我了解,在它后面有一个 sqlite 存储,每个动物的指定实体的每个属性最终都会放在一个表中。这似乎是非常不可取的,考虑到在我的例子中,每个 Animal 都有一个特定属性列表,并且将来应该允许动物的数量增长到大量。

【问题讨论】:

您是否考虑过使用实体继承?将 Cat、Snake 等作为 Animal 的子实体,而不是单独的实体。 @TomHarrington 我已经考虑过了。从建模的角度来看,它是最干净的选择。但据我了解,底层存储将使用包含超级实体和子实体的所有属性的表,因此当您考虑到我有大约 5 个子实体,每个子实体都有 10 个属性时,这不是一个理想的选择。 作为替代方案,您能否创建一个通用的“AnimalProperty”实体,其属性包括“propertyName”(可能的值为“furType”、“beakWidth”等)、“propertyType”(“int ”、“float”、“string”等)和“propertyValue”。然后有一个从 Animal 到 AnimalProperty 的一对多关系。您可以向 Animal 添加一个“animalType”属性,并且需要元数据来指示哪些 animalProperties 适合每个 animalType(例如 Cat = furType, tailLength)。凌乱,但以更复杂的代码库为代价的更简单的模型。 @pbasdf 这肯定会大大降低模型的复杂性。您将如何键入 propertyValue 属性?使用可转换的二进制数据,还是为每种类型设置一个字段? 我个人认为我会使用字符串表示,它应该可以直接转换为简单的整数、浮点数和字符串。它还可能有助于获取谓词(可转换数据和二进制数据不能轻易用于过滤获取)。 【参考方案1】:

这是我到目前为止所采用的方法,以防它对任何人有所帮助(欢迎批评)。

我按照@pbasdf 的建议创建了一个通用属性实体。转换成动物类比模型出来是这样的。

每只动物都与属性具有一对多的关系(“属性”)。属性同时包含一个类型 (Int16) 和一个值 (Binary Data)。根据类型,二进制值被转换为 Float、String、UIColor 或任何与属性类型匹配的数据类型。

最初我将 value 定义为一个字符串,但在切换过程中我注意到性能显着下降。在原始模型中,属性是专门定义的。因此,它们可以直接访问并以正确的类型提供。但是,使用新设置需要两个额外的步骤。 1)根据类型,我们必须首先找到正确的属性。一个动物实例通常少于 10 个,但平均而言,这仍然意味着在找到正确的一个之前必须对一对夫妇进行评估。 2) 从通用值转换为正确的数据类型也会增加时间。使用字符串 (10+) 时,这两个步骤导致属性获取时间显着增加。通过使用二进制属性来存储值,增加被限制在 3-4 倍。当然,如果您需要搜索值,如 pbasdf 所述,字符串更易于访问。

最后我遇到的问题是 Animal 实体仍然属于多个容器,这意味着大量的传入关系会使模型变得混乱。不幸的是,在我的模型中,我不是在处理动物,也不能只是将 Jungle、Zoo 和 WildLifePreserve 转换为通用的 Enclosure 实体。而 Animal 是一个通用的属性容器,它为各种不同的实体提供属性。

【讨论】:

以上是关于减少 Core Data 中的关系数量的主要内容,如果未能解决你的问题,请参考以下文章

Core Data 中的关系同步

如何获取 Core Data 中的关系项属性?

Core Data 中的多重逆关系

如何快速获取 Core Data 中的关系

如何从 Core Data 中的关系相关实体获取属性?

如何管理 Core Data 中的一对多关系?