0

我正在开发一个具有以下多对多模型的项目:

书:可以有多个标签(book.tags) 标签:可以包含很多书(tag.books)

我发现当一本书已经在数据库中时,我只是想通过这样做给那本书添加一个标签[bookMO addTagsObject:tag],我会在 book.tags 中得到一个错误。使用仪器,我发现核心数据正在尝试做“ [NSObject(NSKeyValueObserver(Notification) willChangeValueForKey:withSetMutation:usingObjects]”。

我还检查了实际执行的 sql,我发现:注解:to-many relationship fault "tags" for objectID 0x20140b00fulfilled from database。然后是一个 sql 查询,它返回包含这本书的所有标签。我发现内部核心数据使用书籍和标签的连接表。该连接表的主键只是book_id and tag_id. 该联合表未编入索引。并且要获取包含一本书的所有标签,似乎(我在这里不确定)遍历该联合表中的所有行,因此此操作非常昂贵。

我认为我的应用程序现在发生的事情是,每次我想为一本书添加标签时,我都必须在联合表中进行线性扫描。整体的复杂性是O(N^2)因为每个操作都会在连接表中进行线性扫描。而且我现在有 10k 本书,性能不太好..

有什么办法可以避免tags由 kvo 触发的故障?或者有什么方法可以实现我自己的连接表,可以O(1)通过索引返回结果?

-尔本

4

1 回答 1

0

抱歉更新延迟。

核心数据不适合多对多关系,因为它不会创建我想要的索引。

我最终创建了一个 RleationManagedObject。它具有指向 BookManagedObject 的属性“book”和指向 TagManagedObject 的属性“tag”。两个属性都被索引(非常重要,默认核心数据不索引两个属性)。

每次我需要在“book_1”上添加“tag_1”时,我都会使用“book_1”和“tag_1”搜索所有 RelationManagedObject。如果没有找到,我创建这个relationManagedObject。我还可以使用 <"book_1"、"tag2"> 或 <"book_2"、"tag_1"> 等创建关系管理对象。基本上我自己管理关系。

所以问题是核心数据多对多关系没有正确索引。

此外,xcode 可以打印出它执行的 sql。第一次打开应用程序时,它将创建您在核心数据中定义的那些表。因此您可以看到 CoreData 框架如何在没有正确索引的情况下创建默认的“关系”表。这就是我发现问题的方式。

于 2014-02-09T23:16:03.663 回答