Core data database design issues - ios

I want to create a core data model to store user input questions and then entries for those questions.
The questions will be 1 of 3 types. (1-10, Yes No or a number of specific units). So users will go into the app, click "add question" and will be shown a form where they will input the question title choose the question type (Yes/No, Scale 1-10 or Specific Units) - and if they choose specific units they have to put in those units eg: centimetres, millimetres, litres etc...
There will be multiple entries to these questions mapped over a period of time. IE: Users may put in the questions "How tall is your tomato plant? - specific units - CMs" and "How red are your tomatos? - scale 1-10" and will go back into the app time and again to map out the progress over time.
My question is about database design for this. How would I set this up in my core data?
At the moment I have this:
Now, I'm stuck! I don't quite know how to account for the fact that questions have different types, and therefore the entries will be different.
Plus I need to account for questions where units may be required. These are the questions that will just be a number.
So I'm thinking I probably need different question entites. Something like having a Questions entity and the specific questions as sub-entites - but I'm not sure how to do this, and not sure how to then record the entries made to those questions!
Thank you for looking, and for helping if you can. :)

There's no correct way to design it, and there are indeed many different ways to design a solution.
As #dasdom suggested, you could remove the value from the Entry entity description, and make Entry abstract. Create three subclasses of Entry (BooleanAnswer, RankedAnswer, and ValueAnswer for example). The ValueAnswer would have a decimalValue and units, the others similar related values.
Also, FYI on naming conventions:
Entities: upper case, singular: Question and Entry (though i'd name it Answer)
Attributes/Relationships: lower case: questionText, type, entries, value, questions ('forQuestion' and 'forEntity' are redundant, being the relationship is defined on each of those)
Another option is to have Entity have units, boolValue, rankValue, and decimalValue but only use the attribute that's relevant. That's not an elegant solution, imho.

Related

Problems with Column in Fact Table

I'm building a DW just like the one from AdventureWorks. I have one fact table called FactSales and theres a table in the database called SalesReason that tells us the reason why a certain costumer buys our product.
The thing is there are two types of costumers - the resselers and the online customers - and only the online customers have a sales reason linked to them.
First of all, can I vave to Dimension tables pointing to the same FK in the Fact? Like in my case - Sk_OnlineCustomer and SK_Resseler both point to FK_Customer. Their Id numbers don't overlap-
And Second,
Should I build a reason dimension, link it to the fact and have a FK that most of the times is null or with a "dummy reason"?
Should I just put the reason in the fact sales without it being a key, just like a technical description that is nullable?
Should I divide the fact in two fact tables with one for the resselers and one for the online customers? But even in that case, I would have some costumers that don't answer to the reason, so the fk_reason would be null in some of its appearences in the new fact_Online_Customer.
In a solution I saw from the adventure works tutorial, it's created a new fact table called fact_reason. It Links the factSales with a DimReason.
That looks like a good solution, but I don't know how it works, because I never lerned in my classes that I could link a fact to a fact, thus I wouldn't be able to justify my option to my teacher.
If you could explain it I would appreciate it.
Thanks!
Please find my comments for your questions:
First of all, can I vave to Dimension tables pointing to the same FK in the Fact? Like in my case - Sk_OnlineCustomer and SK_Resseler both point to FK_Customer. Their Id numbers don't overlap-
Yes the dimension in this case would be Dim_Customer(for eg) and this could be a role playing dimension. You can expose reporting views to separate the Online customer and Reseller customer
And Second, Should I build a reason dimension, link it to the fact and have a FK that most of the times is null or with a "dummy reason"?
Yes it would make sense to build a reason dimension. In this you can tag a fact record to the reason
Should I divide the fact in two fact tables with one for the resselers and one for the online customers? But even in that case, I would have some costumers that don't answer to the reason, so the fk_reason would be null in some of its appearences in the new fact_Online_Customer.
I would suggest you keep one fact as your business activity is sales, you can add context to it, online or reseller using your dimensions. If you would prefer you can have separate Dim_Sales dimension to include the sales type and other details of the sales which you cannot include in the dact
To summarise you probably might be well off with the following facts:
Fact_Sales linked to
Dim_Customer
Dim_Sales
Dim_Reason (This can also may be go to the Dim_Sales)
Dim_Date(always include a date dimension when you build a DWH solution)
Hope that helps...

calculated fields: to store in DB or not to store?

I am building a ruby on rails application where a user can learn words from a story (having many stories on his list of stories to learn from), and conversely, a story can belong to many users. Although the story is not owned by the user (it's owned by the author), the user can track certain personal things about each story that relate to him and only to him, such as how many words are left to learn in each of his stories (which will obviously differ from user to user).
Currently, I have a has_many :through relationship set up through a third table called users_stories. My concern/question has to do with "calculated fields": is it really necessary to store things like words_learnt_in_this_story (or conversely, words_not_yet_learnt_in_this_story) in the database? It seems to me that things like this could be calculated by simply looking at a list of all the words that the user has already learnt (present on his learnt_words_list), and then simply contrast/compare that master list with the list of words in the story in order to calculate how many words are unlearnt.
The dilemma here is that if this is the case, if all these fields can simply be calculated, then there seems to be no reason to have a separate model. If this is the case, then there should just be a join model in the middle and have it be a has_and_belongs_to_many relationship, no? Furthermore, in such a scenario, where do calculated attributes such as words_to_learn get stored? Or maybe they don't need to get stored at all, and rather just get calculated on the fly every time the user loads his homepage?
Any thoughts on this would be much appreciated! Thanks, Michael.
If you're asking "is it really necessary to store calculated values in the DB" I answer you. No, it's not necessary.
But it can give you some pros. For example if you have lots of users and the users call those values calculating a lot then it could be more winnable strategy to calculate them once in a while. It will save your server resources.
Your real question now is "What will be more effective for you? Calculate values each time or calculate them once in a while and store in DB?"
In a true relational data model you don't need to store anything that can be calculated from the existing data.
If I understand you correctly you just want to have a master word list (table) and just reference those words in a relation. That is exactly how it should be modelled in a relational database and I suggest you stick with it for consistency reason. Just make sure you set the indices right in the database.
If further down the road you run into performance issue (usually you don't) you can solve that problems then by caching/views etc.
It is not necessary to store calculated values in the DB, but if the values are often used in logic or views its good idea to store it in Database once(calculate again on change) and use from there rather then calculating in views or model.

Core Data Attributes

If I'm making an Entity in Core Data to handle possible values a person can select in a questionnaire form do I have to create an attribute for every possible selectable question? For example my Entity named Person has attributes for name, date, time, and than a bunch of possible answers to select radio-button style that should be added to the Person Entity. Is it better to use a separate Entity for the questionnaire portion.
Edit for better clarity:
The app/survey form is a list of questions with a radio button style check box. If the question applies to them they touch the circle button and it fills in the circle. So its a boolean value. However I'm just not sure if I have to make each one of those questions an boolean attribute or not? This seems like a simple enough project to start learning Core Data which is the purpose of using Core Data instead of some other modeling and persistence solution.
If your properties are y/n answers, that would be boolean attribute e.g.:
Person.licensed = y/n
If your properties have more than y/n possible answer you might use a number attribute:
Person.licensed = 1(y), 0(n), -1(Unknown), -2(Ineligible)
You may need more flexible properties. Maybe there are many types of licenses:
Person.licenses --> Related Entity License with attributes- license.type, license.issueDate, license.expireDate
Then, if you are doing something like a survey, there are many other potential paths. You'll need to elaborate on what you are doing for more help.
Separating the two entities is a good idea as it avoids confusion and keeps your code cleaner. When you step away from the project and return to it 4 months later, there will be no issues discerning where data is saved and from where to retrieve it.
Your Person entity will have its attributes (name, email, etc) and the Questionnaire entity will have its attributes- yes, one for each question with a Boolean type.
Based on your comment you don't need a Boolean or any other attribute. You have a set of questions, which are just instances in the data store. You could group them into a questionnaire if you want, which would be another entity and a relationship between them. Your person is another entity, and has a to-many relationship to question. As the user ticks questions that apply to them you add those questions to the relationship.

CoreData performance duplicate entities vs properties

I'm making an iOS app with thousands of flash cards with questions. The questions pool has about 10,000 questions, and is divided in 5 categories. One single question can have only one category. Categories won't change, they are fixed. Questions are just text. No images involved.
I was thinking about two approaches:
1) Create an Entity for the question with a category field (int) in it.
Fetch the results to get only the questions of a specific category.
2) Create 5 Entities, all with the same fields, except for the category, which has a default value corresponding with the category.
Why option 2?
I think option 1) is the clean proper one, but the app has so many questions that I'm thinking that submitting a query filtering a specific field, is maybe slower than retrieving a completely different Entity. I'm thinking from an SQL point of view, where maybe performing a SELECT on one table and then another one, should be faster than a SELECT...WHERE on the same table?
I agree with you, option 1 is the clean proper one. Retrieving the category from another entity will add minimal overhead. Moreover, if you have to edit a category you have only one entry to change. You can also add other categories more easily.
If you are really concerned about performance (and I don't think you should at that point) you can code both and do a speed test. But that is really overkill and the difference will probably be insignificant.

Properly gathering metadata/object data using Core Data/sqlite [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I'm new to objective c and core data. I am making an iOS app kind of like a flash card app. I have a core data set up with an EnglishWord entity in a many to one relationship with ForeignWord entities (different languages).
For each ForeignWord entity I want to keep track of certain metadata: how many times I have viewed the word, the dates I viewed it, a score I give it, etc. Ideally would be if I could have an array/dictionary as an attribute within the ForeignWord managed object itself. This is not possible.
The only option I can think of is to create a new entity called 'Score', with each ForeignWord entity 'owning' many Score managed objects (one to many), a new 'Score' managed object being created every time I view the foreignWord.
However, this sounds very messy. If I have 1000 words then I would have 1000 different tables in the sqlite database, one for each card.. does that slow things down? is it bad to have 1000 different tables?
is this really the way to do it? Is there a more elegant solution? Thanks!
You might consider adding a table called something like "Viewing" that has a relationship (to 1) both to EnglishWord and ForeignWord. You could then track the metadata that interest you in this table and aggregate the data in this table to determine how many times that you viewed a particular word, whether or not you identified it correctly, etc.
I would create one new table called ViewEntry or something and link relationships to both of your word tables. That way when a word is viewed you can store whatever meta information you want, as well as having an active link to the English and foreign version. Something like this:
This way you can create a new ViewEntry set its foreignVersion and word attributes to the English and foreign words, set the date, score, and total answer time (along with anything else you want). You could then do some really nice querying to pull up useful information.
give me all of the foreign versions of the English word "school" where the score was less than 50%.
I want all of the times the user attempted the Russian translation of "house" and the associated scores.
what English words have the worst/best score?
what is the most/least view English (or foreign) word?
All of this would be relatively easy since the English word could access all of the times it was viewed and any foreign version of any English version could do the same. You could also access the score and view date and pull up all of the English/foreign versions from that data.
You also would not need to create 1000 tables :)

Resources