CoreData 模型设计:过度使用 NSFetchRequest 是否是模型设计不当的症状?
可以使用 NSFetchRequest
或通过跟踪与图中其他对象的关系来检索核心数据对象。公平地说,在一个设计良好的模型中将包含足够的关系(和获取的属性),以便将 NSFetchRequests
的使用保持在最低限度?
反对的论点是,在 iOS 中存在 NSFetchedRequestController
。据推测,如果 Apple 相信关系和获取的属性可以通过现有的故障/缓存提供令人满意的性能,他们就不会创建 NSFetchedRequestController 。
在某些情况下,使用 NSFetchRequest 会更优越,因为 Core Data 可以完成 SQLite 中的所有工作。一个例子是获取聚合值。
对此有什么想法吗?我查看了 核心数据编程指南。 “获取托管对象”和“核心数据性能”部分中有相关建议,但没有强烈建议获取请求之间的关系,反之亦然。
Core Data objects can be retrieved by using an NSFetchRequest
or by following relationships with other objects in the graph. Is it fair to say that in a well designed model will contain sufficient relationships (and fetched properties) such that the use of NSFetchRequests
are kept to a minimum?
The counter argument is that in iOS there exists NSFetchedRequestController
. Presumably if Apple believed that relationships and fetched properties provided satisfactory performance with the existing faulting/caching they would not have created NSFetchedRequestController
.
There are instances when using an NSFetchRequest
are superior as Core Data can do all the work within SQLite. An example would be fetching aggregate values.
Any thoughts on this? I've had a look at the Core Data Programming Guide. There's relevant advice in the 'Fetching Managed Objects' and 'Core Data Performance' sections, but nothing to strongly suggest relationships over fetch requests or vice versa.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想说,关系和 NSFetchRequest 各有其优点和缺点。作为开发人员,您应该知道何时适合使用其中一种。例如,采用以下模型:
如果您想检索属于特定部门的所有员工,那么遵循关系“department.employees”是合适的。使用谓词“department == xxxx”为 Employee 实体创建 NSFetchRequest 是不合适的。
反之,如果你想为某个特定部门寻找薪资>0的员工。 x 那么,使用 NSFetchRequest 和诸如 'department == xxxxx AND salary > 之类的谓词是合适的。 x'。使用department.employees关系检索所有员工,然后循环遍历它们以查找高收入者是不合适的。
总之,关系或 NSFetchRequests 本质上并不是“好”或“坏”。只要适当地使用它们即可。使用关系来导航对象图。使用 NSFetchRequest 执行子集搜索,或者需要灵活地以字典形式返回结果或需要使用 NSExpressions。
编辑添加:
大量 NSFetchRequest 散落在代码中是糟糕设计的标志。我总是将数据请求封装在自定义 NSManagedObject 类中,并尽量不在视图/视图控制器代码中进行任何核心数据调用。
我认为,获取属性是实现相同目标的一种方法。我更喜欢在代码中创建 NSFetchRequest,而不是使用核心数据编辑器来完成它。它更加灵活,但两种方式实际上都是同一件事。
I would say that relationships and NSFetchRequest each have their strengths and weaknesses. As a developer you should know when it is appropriate to use one or the other. For example take this model:
If you want to retrieve all the employees belonging to a particular department then it is appropriate to follow the relationship 'department.employees'. It is not appropriate to create an NSFetchRequest for the Employee entity with predicate 'department == xxxx'.
Conversely, if you want to find employees for a particular department with a salary > x then it is appropriate to use an NSFetchRequest with a predicate like 'department == xxxxx AND salary > x'. It is not appropriate to retrieve all the employees using the department.employees relationship and then iterate over them in a loop to find the high-earners.
In summary, relationships or NSFetchRequests are not inherently 'good' or 'bad'. Just use them appropriately. Use relationships to navigate your object graph. Use NSFetchRequest to perform subset searches or where you need the flexibility of returning results as dictionaries or need to use NSExpressions.
EDIT TO ADD:
A lot of NSFetchRequests littered all over your code is a sign of bad design. I always encapsulate data requests in custom NSManagedObject classes and try not to have any Core Data calls in view/view controller code.
Fetched properties are, I suppose, a way of achieving the same thing. I prefer to create an NSFetchRequest in code rather than use the Core Data editor to do it. It is far more flexible but both ways amount to the same thing really.
一般的经验法则是,数据模型越简单,获取效果越好,而数据模型越复杂,关系效果越好。
例如,如果您的数据模型具有没有关系的单个实体,那么获取将最有效地查找隔离的托管对象。如果您有一个包含十几个实体的数据模型,所有实体都具有两个或多个关系,那么您将大量使用关系。
The general rule of thumb is that the simpler the data model the better fetches work while the more complex the data model the better relationships work.
For example, if your data model has a single entity with no relationships then a fetch will work best to find the isolated managed objects. If you have a data model with a dozen entities all with two or more relationships, then you will use relationships heavily.
当您在 coredata 中设计模型时,您应该记住,如果模式中有 1、2 或 n 个关系,则表明您的对象图将像 SQL 数据库一样运行,因为它只会获取主行,除了您的app 在第一次请求时明确需要所有对象。事实上,出于性能原因,Apple 鼓励在关系之间拆分模型,因此当模型在获取时出现故障时,将会获取其余部分。您应该关心的唯一方面是删除规则(空、级联......),因为设计不当的删除规则可能会崩溃或影响性能。
相信我,我从未见过比核心数据更高效的东西。建立一个强大的模型,核心数据将完成剩下的工作。
我的一个应用程序 (Mariette) 使用核心数据,另一个应用程序 (billingfiles) 使用 SQL
When you design a model in coredata you should keep in mind that if you have 1, 2 or n relations in the mode,l that's Indicate that your object graph will behave as SQL database would because it will only fetch the main rows, except your app explicit need in the first request all the objects. In fact Apple encourage split your model across relations for performance reasons, so when your model fault on a fetch in that moment will fetch the rest. The only aspect you should care about its the delete rules ( null, cascade..) because a bad designed delete rule may crash or affect performance.
Trust me, I've never see nothing so efficient as core data. Make a strong model and core data will do the rest.
One of my apps (Mariette) use core data and another (billingfiles) use SQL