具有多个相似实体或单个大型实体的核心数据

Posted

技术标签:

【中文标题】具有多个相似实体或单个大型实体的核心数据【英文标题】:Core Data with multiple similar entities or single large entity 【发布时间】:2014-12-24 18:40:02 【问题描述】:

我想使用 Core Data 存储 5-10 本书的文本。鉴于每本书都可能很长(想想 30,000 行),我会不会更好:

    创建一个实体以包含具有不同书名的所有书籍(即NSStringattributes 用于 bookTitle、lineNumber、lineText 等)或, 多个实体,每本书一个(具有相同的属性,即 lineNumber、lineText)?

似乎选项 2 更简洁,但只是不确定拥有多个实体是否明智,架构相同,只是名称不同(在逻辑上有意义,因为书籍有不同的名称)

使用下面的代码 sn-p 进行编辑。如果我想过滤以仅搜索一本书实体,我会使用谓词吗?

NSManagedObjectContext *context = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:version
                                              inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    NSError *error;
    NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

【问题讨论】:

【参考方案1】:

此类事物的标准模型是创建一个名为 BookNSManagedObject,并让该实体具有一本书的各种属性,例如标题、作者、文本等。

@interface Book : NSManagedObject 
@property (nonatomic, copy) NSString *title; 
@property (nonatomic, copy) NSString *author;
@property (nonatomic, copy) NSString *text;
...

如果您想将文本分成章节块等,显然会变得比这更复杂。这实际上取决于您的总体设计目标。

【讨论】:

这是有道理的,但是在我的数据模型中,这不意味着我现在只有一个具有这些属性的实体吗?所以说,每当我需要显示一本书的文本内容时,考虑到其他书籍现在都位于一个实体下,我是否也会加载其他书籍的所有数据? 一个 NSManagedObject 是一个类似于数据库记录的单一实体。因此,该行称为 Book,列是标题、作者等。您的核心数据数据库将包含该实体的多个实例。如果加载一本书,则加载一个实体。跨度> 我很抱歉,这里肯定仍处于学习阶段。当您说“该行称为 Book”时,我在这里不太关注的是。我认为完整的数据库是 Book 实体(实体 = 表),因此当您在调用 managedObjectContext executeFetchRequest 时返回数组时,会返回所有行。我的理解真的不正确吗?将使用代码 sn-p 编辑帖子,但如果我只想要一本特定的书而不是所有书,我是否正确地说我需要在我的 fetchRequest 上使用谓词?否则,我不知道如何将其限制为仅与一本书相关的行。 当然。 CoreData DB 包含一堆实体。如果您定义一个 Book 实体,它将为数据库中的每个 Book 包含一个 Book 实体。因此,如果您添加 5 本书,那么它将包含 5 个书籍实体。要访问一本书,您将使用某种选择器在数据库上执行 fetchRequest,该选择器指定您想要的书实体......例如标题。当它找到具有匹配标题的书籍实体时,它将获取整个实体或书籍,然后您可以在书籍文本字段中对您在该书中查找的任何内容进行排序。 @Simply,根据您所描述的两种方式中的哪一种,性能不会明显变快或变慢。通过使用上述答案中描述的实体并将其移动到单独的外部文件中,Core Data 将仅在实际需要时获取书籍的文本。它还将根据需要执行缓存。无论是一个实体还是十个实体都不会产生任何影响。您不是在处理传统的关系数据库系统,除非您有很多非常大的对象,否则这似乎根本不是问题。【参考方案2】:

您可以将其存储在单个实体中,并告诉 Core Data 如果性能受到影响,将文本字段放入单独的“外部”记录文件中。

【讨论】:

【参考方案3】:

更好的方法是创建 2 个实体,一个具有 Book 的元数据,第二个具有实际文本。两个实体都使用一对一的关系进行映射,我们可以创建适当的删除规则。这种方法的优势在于,当您在 UITableView/UICollectionView 中加载书籍列表时,您可以显示标题/作者详细信息,并且元数据会轻得多。当用户点击特定书籍(书名/作者)时,我们可以使用映射获取文本并使用 viewController 显示它。当我们创建映射时,我们已经获得了从关系实体中添加/删除项目的方法

下面是相同的实现:

@interface Book : NSManagedObject 
@property (nonatomic, strong) NSString *title; 
@property (nonatomic, strong) NSString *author;
@property (nonatomic, strong) NSString *genre;
@property (nonatomic, strong) NSString *publication;
....



@interface Bookdata : NSManagedObject 
@property (nonatomic, strong) NSString *Text;

【讨论】:

在列出所有书名时,我确实喜欢这种方法,但如果我的元数据非常有限,仅包括书名和作者,它仍然值得吗?这是否也意味着,如果任何时候我只需要从书中挑出一行,我就需要创建两个 NSManagedObjects 而不是一个?如果我知道书籍的数量会受到限制,我不能在技术上将它硬编码到我的 UITableView 中吗? 我选择退出 2 个实体,因为您的书本可以是任何长度,从几字节到 MB 不等。因此,一次加载所有内容将对应用程序产生性能影响。此外,在设计您的应用程序时,请考虑更广泛的愿景或未来的增强功能,例如如果元数据增加、从服务器加载书籍等......在这种情况下,您的应用程序架构起着重要作用。

以上是关于具有多个相似实体或单个大型实体的核心数据的主要内容,如果未能解决你的问题,请参考以下文章

如何将来自多个视图控制器的数据保存到单个核心数据实体中

核心数据保存和加载到多个实体

具有多个实体和 uitableview 的核心数据

如何在数据库中表示一个实体的许多相似属性?

Spring Boot JPA:将一个实体映射到具有相同列的多个(很多)表

在单个 NSTableView (Core-Data) 中显示来自多个实体的数据