Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

grandM

macrumors 68000
Original poster
Oct 14, 2013
1,551
309
So I was making an app storing a small amount of data. To store this data I'm using Core Data. As I learned about relational databases once upon a time I lied everything out in relationships. Now I'm considering to kick the relationships and extra tables out.

Say for instance you have cars belonging to brands. These brands ought to be put in a separate table. Then you would go putting an 1 to n relationship between Brand and Car. Adding cars to a brand would need an NSSet. It would be possible to look up all the cars of that brand with that NSSet.

Then again if I put everything in one table things would be easier to code. Using an NSPredicate I could easily look up all cars belonging to a peculiar brand. I'm asking this question because it gets more complicated introducing for instance makes. A brand has makes having cars.

The more levels you add the more interesting it gets in theory to use relationships. The code gets more complicated too. Then I start to wonder if that's so interesting if you have a small database. Imagine adding a make. You must first look up if the make already exists etc.
 
I love Core Data and have spent a considerable amount of time with it. I know it very intimately. But what you seem to be questioning at is a general database structure/ORM question.

If you have a fixed set of data, it may be better to not link your tables together via relationships, but in that case, you should definitely do your best to ensure data integrity & flexibility. Core Data's will handle that for you, but you can in code in various ways like enums:

Code:
enum Brand: NSNumber {
    case Ford, Chevrolet;
}

And then store the raw value, using a model subclass to transform the value appriopiately. But you notice how this makes things very rigid, in order to expand your options, you're required to adapt code.

Code:
class Car: NSManagedObject {
    @NSManaged var brandValue: NSNumber

    var brand: Brand {
        set {
            self.brandValue = newValue.rawValue
        }
        get {
            return Brand(rawValue: self.brandValue)!
        }
    }
}

Honestly though, linking via relationships is the ultimate way in this case. Unless there are extenuating circumstances or a very fixed model, your data structure should be as unbound from your hard code model as possible.

Using relationships, you can easily create a predicate, too:

Code:
let brand = Brand.getBrandByName("Ford")
let carsOfBrand = NSPredicate(format: "brand = %@", brand)

Essentially, by using CD relationships, you allow your data to be very flexible and a lot of boilerplate is done for you. You can work in limited contexts with an infinite degree of configuration and easily migrate changes in future iterations.
 
Last edited:
I love Core Data and have spent a considerable amount of time with it. I know it very intimately. But what you seem to be questioning at is a general database structure/ORM question.

If you have a fixed set of data, it may be better to not link your tables together via relationships, but in that case, you should definitely do your best to ensure data integrity & flexibility. Core Data's will handle that for you, but you can in code in various ways like enums:

Code:
enum Brand: NSNumber {
    case Ford, Chevrolet;
}

And then store the raw value, using a model subclass to transform the value appriopiately. But you notice how this makes things very rigid, in order to expand your options, you're required to adapt code.

Code:
class Car: NSManagedObject {
    @NSManaged var brandValue: NSNumber

    var brand: Brand {
        set {
            self.brandValue = newValue.rawValue
        }
        get {
            return Brand(rawValue: self.brandValue)!
        }
    }
}

Honestly though, linking via relationships is the ultimate way in this case. Unless there are extenuating circumstances or a very fixed model, your data structure should be as unbound from your hard code model as possible.

Using relationships, you can easily create a predicate, too:

Code:
let brand = Brand.getBrandByName("Ford")
let carsOfBrand = NSPredicate(format: "brand = %@", brand)

Essentially, by using CD relationships, you allow your data to be very flexible and a lot of boilerplate is done for you. You can work in limited contexts with an infinite degree of configuration and easily migrate changes in future iterations.
I'm doing it the Core Data way but I have a question. Say you have a Class Animal. Then you have the subclasses Cat and Dog. Cat and Dog are linked to other things in Core Data using relationships. As Both belong to Animal and I want to store for instance the birthday in Animal how are you putting that together in Core Data? Do you put a 1 to 1 relationship between Animal and Cat? Or can you indicate in Core Data that Cat is a subclass of Animal?
 
I love Core Data and have spent a considerable amount of time with it. I know it very intimately. But what you seem to be questioning at is a general database structure/ORM question.

If you have a fixed set of data, it may be better to not link your tables together via relationships, but in that case, you should definitely do your best to ensure data integrity & flexibility. Core Data's will handle that for you, but you can in code in various ways like enums:

Code:
enum Brand: NSNumber {
    case Ford, Chevrolet;
}

And then store the raw value, using a model subclass to transform the value appriopiately. But you notice how this makes things very rigid, in order to expand your options, you're required to adapt code.

Code:
class Car: NSManagedObject {
    @NSManaged var brandValue: NSNumber

    var brand: Brand {
        set {
            self.brandValue = newValue.rawValue
        }
        get {
            return Brand(rawValue: self.brandValue)!
        }
    }
}

Honestly though, linking via relationships is the ultimate way in this case. Unless there are extenuating circumstances or a very fixed model, your data structure should be as unbound from your hard code model as possible.

Using relationships, you can easily create a predicate, too:

Code:
let brand = Brand.getBrandByName("Ford")
let carsOfBrand = NSPredicate(format: "brand = %@", brand)

Essentially, by using CD relationships, you allow your data to be very flexible and a lot of boilerplate is done for you. You can work in limited contexts with an infinite degree of configuration and easily migrate changes in future iterations.
I just noticed I can indicate the Parent entity so I guess I don't need a relationship between Animal and Cat then?
 
You are correct, the latter example using inheritance as Cat or Dog are a more defined Animal. Essentially, they are not related, they are of one.

Core Data supports inheritance (parents), but you need to keep in mind that entity inheritance is not the same as object inherence and I've been burned by performance problems when using a SQL lite store, complicated data paradigms, and large active datasets (and others, as you can see here and here).
 
You are correct, the latter example using inheritance as Cat or Dog are a more defined Animal. Essentially, they are not related, they are of one.

Core Data supports inheritance (parents), but you need to keep in mind that entity inheritance is not the same as object inherence and I've been burned by performance problems when using a SQL lite store, complicated data paradigms, and large active datasets (and others, as you can see here and here).
I just look a quick look at the threads. Are you advising me not to use inheritance? It seems normal to me that the fields from the parents could be filled in on the child level. I do not want a slow app though.

Even more, in a normalised database (as mine is at the moment) it seems a bit hard now and then for the predicates. I 'm also adding all records in the relationships with NSSet, at times it seems a lot of work.
 
I just look a quick look at the threads. Are you advising me not to use inheritance? It seems normal to me that the fields from the parents could be filled in on the child level. I do not want a slow app though.

Even more, in a normalised database (as mine is at the moment) it seems a bit hard now and then for the predicates. I 'm also adding all records in the relationships with NSSet, at times it seems a lot of work.

Totally suggesting that you to use inheritance, but also to be aware of repercussions to take into account when planning your model. Always weigh the pros and cons for your particular situation with as much knowledge as you can amass (hence why I refer you to those posts, so you can have all of the information available to you). Personally, I have used inherence in many of my apps, but also rarely plan on managing more than a few thousand entries - if theres a better chance in which inheritance can improve the overall flow of my app than slowdown occurring, I'm going to use it.

Do you have any specific examples I can help you out with? A lot of the time, predicates can be simplified or explained in ways that may not be so obvious. It's good to learn the details, such as collection operators and subqueries since it's not really SQL syntax.
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.