使用SQL数据存储,我有一个如下所示的模型:
类别<->>项目
收集<->>项
品牌<->>项目
每个左侧实体都有一个名为items的到Item实体的多个关系。每一项都与类别、集合和品牌的一对一关系相反。
我想拿所有的品牌对象与至少一个项目与一个特定的集合和类别。在自然语言,我想要所有的品牌与特定的类别和特定的收藏。
给定对象类别* objects和Collection *myCollection,我使用这种方式在品牌实体上构建谓词:
NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"(ANY items.category == %@) AND (ANY items.collection == %@)",myCategory,myCollection];
我得到了正确的结果。问题在于性能。太慢了!我把这个问题简化为三个层次!让我们考虑iOS多级目录中的四个级别:应用程序显示可用类别,用户选择一个类别,应用程序显示该类别中的集合,用户选择集合,应用程序显示该集合中的品牌(以及已经选定的类别),用户选择一个品牌,应用程序显示该品牌中的材料、集合和类别.
老实说,我使用NSCompoundPredicate在每个用户选择时插入和子谓词,动态地构建最终谓词。但就这个问题而言,这并不重要。
在sql数据存储中,项实体有30,000 (30k)多个对象,项关系的使用和之间的使用非常缓慢(在上面的示例中,我注意到显示品牌的滞后时间为7-10秒)。
我试着:
-remove 项目--来自类别、收藏和品牌实体的关系
-on项目实体,将类别、集合和品牌关系替换为获取"category_id“、"collection_id”和"brand_id“等属性的属性。
-use键盘或谓词获取品牌,而不使用-许多关系。
在我开始破坏和改造过去6个月的全部工作之前,你有什么建议吗?
谢谢!
发布于 2011-10-26 00:22:18
颠倒你正在寻找的东西的逻辑。
您不是在寻找具有特定类别和特定收藏的品牌,而是在寻找具有X类别和Y集合的项目实体。一旦您拥有了该项目,您可以要求它提供它的品牌:
id myCategory = ...;
id myCollection = ...;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Item"];
[request setPredicate:[NSPredicate predicateWithFormat:@"category == %@ && collection == %@", myCategory, myCollection]];
NSError *error = nil;
NSArray *itemArray = [moc executeFetchRequest:request error:&error];
NSAssert2(!error || itemArray, @"Error fetching items: %@\n%@", [error localizedDescription], [error userInfo]);
NSArray *brands = [itemArray valueForKey:@"brand"];
return brands;
更新
项目是关系的另一端的一个实体,就像你在问题中一样。-valueForKey:
将遍历项目数组,并在关系的另一端获取品牌实体,并给出一个品牌数组。您不需要添加任何内容,甚至不需要添加一个属性,因为它将通过KVC访问,并将“仅起作用”。
这将为您提供基于您的需求的最有效的检索。由于Item位于这些关系的多个方面,它将保存外键,因此SQL不需要跨表边界,因此应该非常快。
唯一的其他选择,我不推荐它,但你可以玩的集合来自类别和集合,并从一个可变的集合获得一个联合。每次我尝试这个方向的时候,它都比进入数据库要慢。在我看来,这种逻辑最好是在数据库级别完成。
https://stackoverflow.com/questions/7896151
复制相似问题