Re: Is Core Data appropriate to my task?
Re: Is Core Data appropriate to my task?
- Subject: Re: Is Core Data appropriate to my task?
- From: Gwynne Raskind <email@hidden>
- Date: Thu, 10 Sep 2009 18:29:01 -0400
Before anything else, let me say thank you for a clear, concise, and
very helpful set of answers to my questions; I was expecting rather
more of a struggle for understanding :).
On Sep 10, 2009, at 5:04 PM, Ben Trumbull wrote:
support for such a thing; I would either have to write a custom
property type or model it by creating the Planet entity and giving it
a relationship from Employee.
Correct. You can write a custom NSValueTransformer with the
Transformable property type to implement an ENUM, or normalize the
data into a separate table as a formally modeled entity. Which is
better depends on how big the data values are, how many of them
there are, and how frequently they change.
Is that really so bad ? The alternative is to do ALL the work
yourself.
Mostly I just wanted to be certain that there was nothing obvious I
was missing :).
The inverse
relationship from Planet to Employee, "all employees from this
planet"
is technically feasible, even easy, to model, but it's almost
certainly a waste of time and effort. But the Core Data documentation
offers a long list of very dire warnings about one-way relationships
between entities.
Yes, and for most situations those warnings are there for very good
reasons. But if there were no reasons for such relationships, then
it wouldn't be a warning, it simply wouldn't exist.
The manual isn't at all clear about this, but if I understand
correctly, you're basically saying, "Though it is almost always
technically possible to model an inverse to any relationship, there
are sometimes circumstances in which it is correct not to do so." Is
that accurate, and if so, should I file a documentation bug requesting
clarification on that and the circumstances in which it's true?
Worse, the list of possible Planets certainly doesn't belong in the
same document file that holds a single Employee's data; you'd end up
duplicating that data across every single Employee. So the list of
Planets would instead be in a global store.
There are lots of ways to model that, but, yes, this would be the
most natural.
I can't think of any others offhand, but I haven't worked with this
sort of data before; could you give some examples?
But oops, Core Data can't
model cross-store relationships, so you use a fetched property, which
is one-way.
You could use a fetched property, or handle this in code by storing
a URI for the destination object in a different store, and fetching
the matching objectID either lazily in in -awakeFromFetch. We've
generally recommended using a custom accessor method for this
instead of fetched properties.
Is there any particular reason for that recommendation? The
documentation explicitly recommends fetched properties for cross-store
relationships (one instance of several is in the Core Data Programming
Guide, "Relationships and Fetched Properties" chapter, "Fetched
Properties" section, first paragraph, where it says " In general,
fetched properties are best suited to modeling cross-store
relationships...")
Also, if you do in code or fetched properties, this hand made cross
store relationship, you should prefer numeric keys to text strings
for your joins. Creating a de facto join through a LIKE query is
pretty crazy. That's a case insensitive, local aware, Unicode regex
there. String operations are much more expensive than integer
comparisons. At the very least, use == for your string compares.
Don't worry, I already had the experience of having to work with a
codebase that used string keys as its only cross-table links in mSQL.
Eventually we had to recreate the whole system from scratch.
It seems to me that Core Data really is intended to deal with lists
of
root objects, i.e. the entire list of Employees in one store, rather
than one Employee per store.
One document per Employee is a bit unusual. But it's feasible if
that's your requirement.
Employee was just the example I yanked out of the Core Data docs :). A
better analogy would be the "Picture" example. If you use Core Data
entities to store the various elements of a vector graphic, you would
certainly want to be able to store one graphic per document.
(Let me take this opportunity to say that for all the warnings that
Core Data is not and never has been a database, almost every
concept I
see in it makes me think "O/R mapper for SQLite".)
Core Data is an O/R mapping framework, among other things. But O/R
frameworks are not SQL databases. Modeling your data in any O/R
framework as if you were writing SQL directly is inefficient and
mistaken.
Saying that Core Data is a database is like saying your compiler is
an assembler. Well, the compiler suite uses an assembler, sure, and
they both output object code in the end, but that does not mean the
best way to use your compiler is to write in assembly.
Nonetheless, Core Data does manage the data stored on disk as well as
the representation of that data in memory; I don't see a tremendous
difference between that and what SQLite does, other than Core Data
providing a much effective organization of and means of access to that
data.
-- Gwynne
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden