2013-10-01 80 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如何在沒有正確編制索引的情況下創建默認的「關係」表。這就是我如何找到問題。