2013-10-01 47 views
0

我工作的一个项目具有以下众多一对多模式:核心数据多到许多关系更新导致故障

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

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

我还检查了执行的实际sql,我发现: 注释:从数据库中完成的objectID 0x20140b00的多对一关系错误“标记”。 ,然后返回一个sql查询,它返回包含这本书的所有标签。我发现内部核心数据使用Book和Tag的连接表。该连接表的主键只是book_id and tag_id的组合。该联合表格没有编入索引。为了获得所有包含书籍的标签,似乎(我不确定)遍历该联合表中的所有行,因此此操作非常昂贵。

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

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

-Erben

回答

0

遗憾的延迟更新。

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

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

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

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

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