The only databases I've worked with before are MySQL so the database design of CoreData is confusing me a little bit.
Briefly, the design consists of a many-to-many relationship between people and businesses. Many people can own one business. One person can own many businesses.
In this simplified design, there are 3 tables:
PERSON BUSINESS OWNED BUSINESS
------ -------- --------------
id id personID
name name businessID
email website acquisitionDate
The OwnedBusiness table is the one that's confusing me. In MySQL, this table is used to support many-to-many relationships. I understand that CoreData doesn't require this, however I have an extra field in OwnedBusiness: acquisitionDate.
Does the extra field, acquisitionDate warrant the use of the extra entity/table? If not, where would that field go?
First, Core Data is not a database, full stop.
Core Data is an object graph management framework, your model in your application.
It can persist to disk in a database. It can also persist as binary, XML and just about anything else. It does not even need to persist.
Think about Core Data as an object graph only. In your example you would have a Person entity, a Business entity and a OwnedBusiness entity.
The OwnedBusiness entity would have two relationships and one property. You would not manage the foreign keys because Core Data handles that if you end up persisting to a database. Otherwise they are object pointers.
So first of all, CoreData is not a relational db just to clear this out.
Second, I think you should have a quick look at CoreData documentation and since you are familiar with MySql it will be an easy reading and I think you will be kind of amazed by the extra features that CoreData provides.
Regarding the many-to-many relationship, CoreData support this relationship without the need of extra tables. Also the relationship are not based on ids, they are based directly on objects.
So in your case, you don't have to use the person id & business id to create the relationship, you can create the relationship in the Relationship section of your xcdatamodel, there you can set the relationship class (or Destination), an inverse to that relationship (useful thing) and of course the type of relationship (to-many, to-one).
So to answer your question, you can add it there depending on your business logic. As a short advice, pleas don't try to normalise the database as you would do on a normal MySql instance, you will loose lot of performance by normalising, this thing is often ignored by devs.
Related
I'm struggling with creating a suitable Core Data model for my app. I'm hoping someone here can provide some guidance.
I have two entities -- "Goals" and "Items". The Goals entity contains only a goal description, but any goal may have any number of subgoals, and these may extend multiple levels in a tree structure. Subgoals are to be contained within the same entity, so presumably the Goal entity will contain a pointer to "parent" which will be the parent goal of any subgoal.
There will also be an "Items" entity that contains a couple of text fields and a couple of binary items, and must be linked (ideally, by a unique identifier, perhaps objectID) to the particular goal or subgoal the item(s) are related to.
I am totally fumbling with how to set this model up. I know what attributes need to be in each entity, but the relationships, particularly between goals and "subgoals", has me stumped. I don't seem to be able to turn up any good examples of tree structures in Core Data on the Internet, and even the couple of books I have on Core Data don't seem to address it.
Can anyone here help an old SQL programmer get headed the right direction with these relationships in Core Data? Thanks.
Have you tried creating a one-to-many from Goal to itself, and a one-to-one from Goal to Item? The only thing I would worry about here is circular references.
Also, read Relationships and Fetched Properties in the CoreData Programming Guide.
Here is how it is done:
You set up a to-many relationship from Goal to Item in the model editor. Don't use any ids, foreign keys etc. This is old-fashioned database thinking - you can forget about it. Here we are only dealing with an object graph. The database layer is just an implementation detail for persisting the data.
Make two more relationships in entity Goal to itself: a to-one called parent, a to-many called subGoals. Make them the inverse of each other. Simple!
QED is correct, you can create a to many relationship on goal (call it subgoals) as well as a to-one relationship on goal (call it parentGoal) and set them as inverses to each other.
Then create another to many relationship (call it items) on the goal entity, with the inverse being a to one relationship on the item entity (call it goal). Then you're all set. You don't need to link items with a unique id, just add them to the items relationship.
Also note that if you did want to give items a unique id, do not use the objectID. The objectID should only be used as a temporary id as they are not guaranteed to remain the same. In fact they will change if you ever do a Core Data migration.
One way, though not really great, is to create a another entity, say subGoal, and each goal has one subGoal and each object of subGoal has many goal.
I do have some JSON file http://jsonblob.com/530664b3e4b0237f7f82bdfa I am pulling from forecast.io.
I am little confused how I should be creating my CoreData entities and relationships.
In below setup, I made my Location entity as the parent entity and created a separate entity for Currently, Minutely, Hourly, Daily. However I have decided it's best to hold all the information regarding the weather data in one entity, so I created a Data table for that purpose and tied it to Daily and Currently in the image below.
Before going further, I paused and would like to get a second opinion on it. Is this a valid way of going forward with this?
EDIT: Based on Wain's response I changed my model to this
Currently Minutely and Hourly add little value as they don't have any attributes or relationships. It's also generally easier to add a type attribute rather than having a number of sub entities because you can easily filter the type using a predicate while doing a fetch. If you're going to add more in the future then there could be a case for keeping sub entities.
Once the entities are trimmed down then you only have a Location and Data with a relationship. You should make that relationship bi-directional so that Core Data can manage the data store contents better. (this applies to all relationships, even if you keep the sub entities you already have).
Other than that, fine :-)
I and my team are all beginners with NoSQL, were still wearing the Entity Framework with SQL Server 2008 on a project but with the passage of time the project was getting bigger and more complex than the EF does not resolve more for us, we decided to adopt the MongoDB, but we still have many doubts due to great paradigm shift, I'll post them here to see what you guys think and your opinions.
I have the entities "Person Fisica", "Patient" and "professional" and the patient and the Professional are Person, but in a few moments the patient and the professional will be the same person ex (a professional health unit which is also patient) in SQL Server we had a patient who had a reference to the Physical Person and professional who also had a reference to the PersonWhen Patient and Professional were the same person, the two had references to the same Person, now at mongo appeared doubts, some team members here want to do the same thing pretty much, Patient and professional organizations have the Id of the Person. Now I wanted to make the patient and the professional have the full object Person, but oh how would the integrity of this? Because technically the Physical Person of the Patient would be different from the Physical Person of professional ... This and other questions are breaking our heads here, in several entities that are shared do not know if we put the entity within the object that has it or the object only takes the Id of the entity, in the same way as in relational DB. Another example: the Health Unit and the types of UnidadeDeSaude, a type Of Health Unit has several Health Units and a Health Unit has a type, the correct approach would be to place the Unit Type object within the Health Unit or just reference it by Id?
Googled a few articles, but we're still in doubt in these cases
http://highlyscalable.wordpress.com/2012/03/01/nosql-data-modeling-techniques/
http://blog.fiesta.cc/post/11319522700/walkthrough-mongodb-data-modeling
Without being able to see exactly what you have, so speaking generally, in MongoDB you wouldn't JOIN tables in the same way you would with a RDBMS. Typically, if you have a Person entity you store the whole Person as a Person. This is a nice mapping from your code classes.
In the case where you have references to other entities, say where a single Person is shared between Patient and Professional you would do this with a foreign key reference in a RDBMS. You can do this with Mongo but Mongo won't do the JOIN for you. That would have be done by the caller. The recommended approach is to put a copy of the Person entity in both Patient AND Professional. The impact of this means that if you update the Person entity you now have to update the data in two places, but that's not necessarily as bad as it sounds. It's usually "quick" to update and you can update both 'atomically' so in practice there's little difference between that and updating a single entity except that you don't have to do the JOIN so your reads are simpler and usually faster.
The most powerful tool you have for fetching data is the Collection's (table's) index over your documents (entities) and any way you can leverage that will be the fastest way to return data. So counter intuitively, if you need to filter and process parts of a document more often than you need the whole, you are better to break it up into entities that share an indexed key. That would mean storing Person, Patient and Professional in the same collection and using two keys. One key is shared by the Person and it's derived class (Patient) and the other is a type discriminator that selects one part or the other. In other words, use the index to find whole entities, or collections of whole entities.
Aside from that, if once you have used the index to locate an entity, Person, Patient or Professional, read the whole entity and have it contain everything you need to fulfill the request without a JOIN. So whether you request the Patient or the Person (both refer to the same Person) you get the same Person data whichever object you read.
In short, you'll be replicating data in Mongo just about anywhere you'd have used a Join in SQL.
Are you able to draw what your class hierarchy looks like?
I have a MySQL database and would like to have a similar structure in Core Data. I am very new with using Core Data with Xcode. I have a few fundamental questions if I am doing the right thing.
My Mysql DB looks similar to this:
table.caveconditions
visibilityID
percolationID
xxxx
table.visibility
visibilityID
visibilityValue
...and so on. I would then connect the tables using JOINS
Now, I have done the Core Data modeling like this but I am not quite sure if this is the right approach.
Would be great if someone of you could tell me if this is the right way to do it. In the end I would like to use JSON strings to dump the mysql table into core data.
Thanks a lot
Chris
I have created the new schema. Is this right?
It looks good except for all the "xxxID" attributes e.g. caveID. You also need to follow the naming conventions.
You have the same attribute names with (presumably) the same values in two or more entities. This is necessary in SQL for joins but in Core Data, this is handled by objects and relationships.
Each object in Core Data is automatically universally unique. This means when you create a relationship from one object to another, that relationship concrete identifies on specific unique object.
This means you only need an attribute like caveID in the actual entity that caveID designates which in this case is (presumably) the Caves entity. You don't need the attribute in the CavesConditions entity or any other entity that has a relationship to the "Caves" entity.
(If the xxxID were just artifacts of SQL, you don't actually need them at in Core Data unless some external database your app interacts with requires them.)
A good rule of thumb to use is that any particular value should show up on only one side of a relationship and, ideally, only once in the entire data model.
Naming conventions are a little different than SQL. A Core Data entity isn't a table. An entity is more akin to a class. Each entity is supposed to describe a single instance of a managed object. How many of those instances end up in the object graph is irrelevant. Therefore, entity names are singular.
In this case, Caves should be Cave, Countries should be Country and so on.
Relationships are named after the entity they target. It is not immediate obvious but each reciprocal relationship (the default) on the visual data model editor is actually two relationships because there is one relationship description for each side. Each side has the name of the entity targeted. By convention to-one relationships have a singular name and a to-many relationship has a plural name.
So:
Caves.relConditions<-->>CaveConditons.getCave
...would become
Cave.conditons<-->>CaveConditon.cave
The naming conventions are important because Objective-C uses conventions names to generate and search for accessor methods.
CoreData is NOT a database. Remodel your data as simply as you can and in a way that suits how it will be used in your application and do not think about joins or structure based optimization. You do not have control over the backing schema of a CoreData object model. This is the hardest concept you must get over when starting to use CoreData, but once you do, you will be better off.
I'm using MS SQL Server 2008R2, but I believe this is database agnostic.
I'm redesigning some of my sql structure, and I'm looking for the best way to set up 1 to many relationships.
I have 3 tables, Companies, Suppliers and Utilities, any of these can have a 1 to many relationship with another table called VanInfo.
A van info record can either belong to a company, supplier or utility.
I originally had a company_id in the VanInfo table that pointed to the company table, but then when I added suppliers, they needed vaninfo records as well, so I added another column in VanInfo for supplier_id, and set a constraint that either supplier_id or company_id was set and the other was null.
Now I've added Utilities, and now they need access to the VanInfo table, and I'm realizing that this is not the optimum structure.
What would be the proper way of setting up these relationships? Or should I just continue adding foreign keys to the VanInfo table? or set up some sort of cross reference table.
The application isn't technically live yet, but I want to make sure that this is set up using the best possible practices.
UPDATE:
Thank you for all the quick responses.
I've read all the suggestions, checked out all the links. My main criteria is something that would be easy to modify and maintain as clients requirements always tend to change without a lot of notice. After studying, research and planning, I'm thinking it is best to go with a cross reference table of sorts named Organizations, and 1 to 1 relationships between Companies/Utilities/Suppliers and the Organizations table, allowing a clean relationship to the Vaninfo table. This is going to be easy to maintain and still properly model my business objects.
With your example I would always go for 'some sort of cross reference table' - adding columns to the VanInfo table smells.
Ultimately you'll have more joins in your SP's but I think the overhead is worth it.
When you design a database you should not think about where the primary/foreign key goes because those are concepts that doesn’t belong to the design stage. I know it sound weird but you should not think about tables as well ! (you could implement your E/R model using XML/Files/Whatever
Sticking to E/R relationship design you should just indentify your entity (in your case Company/supplier/utilities/vanInfo) and then think about what kind of relationship there is between them(if there are any). For example you said the company can have one or more VanInfo but the Van Info can belong only to one Company. We are talking about a one – to- many relationship as you have already guessed. At this point when you “convert” you design model (a one-to many relationship) to a Database table you will know where to put the keys/ foreign keys. In the case of a one-to-Many relationship the foreign key should go to the “Many” side. In this case the van info will have a foreign keys to company (so the vaninfo table will contain the company id) . You have to follow this way for all the others tables
Have a look at the link below:
https://homepages.westminster.org.uk/it_new/BTEC%20Development/Advanced/Advanced%20Data%20Handling/ERdiagrams/build.htm
Consider making Com, Sup and Util PKs a GUID, this should be enough to solve the problem. However this sutiation may be a good indicator of poor database design, but to propose a different solution one should know more broad database context, i.e. that you are trying to achive. To me this seems like a VanInfo should be just a separate entity for each of the tables (yes, exact duplicate like Com_VanInfo, Sup_VanInfo etc), unless VanInfo isn't shared between this entities (then relationships should be inverted, i.e. Com, Sup and Util should contain FK for VanInfo).
Your database basically need normalization and I think you're database should be on its fifth normal form where you have two tables linked by one table. Please see this article, this will help you:
http://en.wikipedia.org/wiki/Fifth_normal_form
You may also want to see this, database normalization:
http://en.wikipedia.org/wiki/Database_normalization