Data model for SCORM in Rails application - mysql

I would like to partially implement SCORM standard in my Rails app.
My current data model has the following structure. I have users, I have courses, I have join table user_courses (each row is data for the course started by some user). The latter table has all attributes (columns) that SCORM requires to implement (max score, min score, raw score etc.)
Everything is plain and easy until I get to objectives. It says that SCORM-compliant LMS should support at least 100 objectives. If it were only 4 or 5, I would create 4 or 5 more columns in my user_courses table, but it doesn't have any sense to create 100 as user will probably use 5 to 10.
What is the best way to handle such problem?

How do objectives relate to the current tables?
EDIT:
I'm assuming a course will have a pre-set Objectives and they won't need to track these objectives seperatly per user.
Create table: objectives with objective_id
Create table: course_objectives with course_id, objective_id
You can link course to course_objectives (a course has many objectives) and link objectives to course (an objective can belong to many courses). This will allow you to re-use common objectives between courses. If this is not the case, then you can skip course_objectives and just use objectives to course as, a course can have many objectives.
Does this help?
If you do need to track the progress or status of objectives per user, you'll need another table between user_courses and course_objectives.
-Dan

Related

Split similar data into two tables?

I have two sets of data that are near identical, one set for books, the other for movies.
So we have things such as:
Title
Price
Image
Release Date
Published
etc.
The only difference between the two sets of data is that Books have an ISBN field and Movies has a Budget field.
My question is, even though the data is similar should both be combined into one table or should they be two separate tables?
I've looked on SO at similar questions but am asking because most of the time my application will need to get a single list of both books and movies. It would be rare to get either books or movies. So I would need to lookup two tables for most queries if the data is split into two tables.
Doing this -- cataloging books and movies -- perfectly is the work of several lifetimes. Don't strive for perfection, because you'll likely never get there. Take a look at Worldcat.org for excellent cataloging examples. Just two:
https://www.worldcat.org/title/coco/oclc/1149151811
https://www.worldcat.org/title/designing-data-intensive-applications-the-big-ideas-behind-reliable-scalable-and-maintainable-systems/oclc/1042165662
My suggestion: Add a table called metadata. your titles table should have a one-to-many relationship with your metadata table.
Then, for example, titles might contain
title_id title price release
103 Designing Data-Intensive Applications 34.96 2017
104 Coco 34.12 2107
Then metadata might contain
metadata_id title_id key value
1 103 ISBN-13 978-1449373320
2 103 ISBN-10 1449373320
3 104 budget USD175000000
4 104 EIDR 10.5240/EB14-C407-C74B-C870-B5B6-C
5 104 Sound Designer Barney Jones
Then, if you want to get items with their ISBN-13 values (I'm not familiar with IBAN, but I guess that's the same sort of thing) you do this
SELECT titles.*, isbn13.value isbn13
FROM titles
LEFT JOIN metadata isbn13 ON titles.title_id = metadata.title_id
AND metadata.key='ISBN-13'
This is a good way to go because it's future-proof. If somebody turns up tomorrow and wants, let's say, the name of the most important character in the book or movie, you can add it easily.
The only difference between the two sets of data is that Books have an
IBAN field and Movies has a Budget field.
Are you sure that this difference that you have now will not be
extended to other differences that you may have to take into account
in the future?
Are you sure that you will not have to deal with any other type of
entities (other than books and movies) in the future which will
complicate things?
If the answer in both questions is "Yes" then you could use 1 table.
But if I had to design this, I would keep a separate table for each entity.
If needed, it's easy to combine their data in a View.
What is not easy, is to add or modify columns in a table, even naming them, just to match requirements of 2 or more entities.
You must be very sure about future requests/features for your application.
I can't image what type of books linked with movies you store thus a lot of movies have different titles than books which are based on. Example: 25 films that changed the name.
If you are sure that your data will be persistent and always the same for books and movies then you can create new table for example Productions and there store attributes Title, Price, Image, Release Date, Published. Then you can store foreign keys of Production entity in your tables Books and Movies.
But if any accident happen in the future you will need to rebuild structure or change your assumptions. But anyway it will be easier with entity Production. Then you just create new row with modified values and assign to selected Book or Movie.
Solution with one table for both books and movies is the worst, because if one of the parameters drive away you will add new row and you will have data for first set (real book and non-existing movie) and second set (non-existing book and real movie).
Of course everything is under condition they may be changes in the future. If you are 100% sure, then 1 table is enough solution, but not correct from the database normalization perspective.
I would personally create separate tables for books and movies.

Difference between two separate tables and one table with column

I have users and doctors. It is an app that both regular people and doctors can use. I'm not sure which way to setup my database.
Two tables - users and doctors tables
One table, extra column - users table with column user_type
Which one is the best way to do it? What are the pros and cons of both?
Keeping separate tables for me is good especially if you make user table to be as basic as possible (with username and password). This way you know that even if requirements changes in the future and you need to add another user type with other additional fields, then you don't have to worry about other sections of your code. I am just thinking about the future changes or additions. Doctors is abstract. Again this might be the problem in the future when you have to categorize them (e.g by their specialty).
Just my two cents worth.
2 tables is your best approach. Although not the 2 tables you have suggested.
If you analyze your situation a little more basically, you have users and they belong to 1 of 2 groups (general public and doctors).
This is a standard user group situation, so using 1 table to store user specific data with a reference to a user_group table (ie user belongs to group) is a good solution.
This also allows you to add groups later on - renal patient, renal doctor, cardiac patient, cardiac doctor ...
Using a setup with users and user_groups is usually a good way to go.

Database model for user ratings / reviews

What is the best way of modeling user reviews and scores in a database?
So the problem description would be the following:
Imagine we had users who can rate items (give a score to an item), but
can also write reviews (with title, content, and also a score), and
maybe even submit more types of reviews, such as video reviews (with a
video and also a score for instance).
Also, users can rate other user's reviews.
I've came up with the following EER diagram for this problem (does not include attributes nor the relationship between REVIEW and USER that would allow users to rate reviews):
In the design above, the different types of reviews (written review or video review) could be modeled by using inheritance, either in the same table using an attribute to differentiate between types or with a table per subclass.
An alternative to this design would be to consider the RATING table another type of review (one with no content or title, just a score), and use inheritance to model all the review types (scores, written reviews and video reviews). The problem I see with approach though is that I would need 2 relationships to allow users to rate reviews (one with written reviews and another one with video reviews), and would make it more difficult as well to retrieve all users reviews (written and video reviews).
Do you think one approach is better than the other (I'm leaning towards the first), or is there a better way of modeling this scenario?

Issues with Schema Design

I am designing a database having the following entities :
Student_detail : has id as PK and rest some attributes.
Event : Has the details about different events. event_no is PK. (there are about 32 events)
Participates_in : is a relation between student_detail and event, has both their PKs as FKs.
Team_with : this is a relation from student_detail table to itself, it has 8 participant columns, one team_id column, one for_event_no column(FK to event_no). All the participant columns are FKs to student_detail.id.
One row of this column indicates a team for a specific event.
The number 8 because, the max team size in all events is 8.
Events have variable number of allowed team sizes.
I devised the team_with table in order to avoid creating 30 different tables for different event.
Due to this, query length is increasing. Is this good design? I would like suggestions for this.
Do all members of a team have equal membership? If there were 8 fixed roles in a team, I would agree with your design. If not, I suggest:
teams (team_id PK, for_event_no FK)
team_members (team_id PK/FK, student_detail_id PK/FK)
However, enforcing a maximum team size of 8 could be more difficult. I don't see this as a significant problem since you say different events allow different team sizes, so the limit of 8 could be incorporated into that mechanism, however it's implemented.
What's the difference between participation in an event and membership of a team associated with the event? There's already a relation between Event and Student_detail - directly in your Team_with, and transitively in my suggestion. Participates_in may be redundant, unless participation is possible without being part of a team.

Proper way to model user groups

So I have this application that I'm drawing up and I start to think about my users. Well, My initial thought was to create a table for each group type. I've been thinking this over though and I'm not sure that this is the best way.
Example:
// Users
Users [id, name, email, age, etc]
// User Groups
Player [id, years playing, etc]
Ref [id, certified, etc]
Manufacturer Rep [id, years employed, etc]
So everyone would be making an account, but each user would have a different group. They can also be in multiple different groups. Each group has it's own list of different columns. So what is the best way to do this? Lets say I have 5 groups. Do I need 8 tables + a relational table connecting each one to the user table?
I just want to be sure that this is the best way to organize it before I build it.
Edit:
A player would have columns regarding the gear that they use to play, the teams they've played with, events they've gone to.
A ref would have info regarding the certifications they have and the events they've reffed.
Manufacturer reps would have info regarding their position within the company they rep.
A parent would have information regarding how long they've been involved with the sport, perhaps relations with the users they are parent of.
Just as an example.
Edit 2:
**Player Table
id
user id
started date
stopped date
rank
**Ref Table
id
user id
started date
stopped date
is certified
certified by
verified
**Photographer / Videographer / News Reporter Table
id
user id
started date
stopped date
worked under name
website / channel link
about
verified
**Tournament / Big Game Rep Table
id
user id
started date
stopped date
position
tourney id
verified
**Store / Field / Manufacturer Rep Table
id
user id
started date
stopped date
position
store / field / man. id
verified
This is what I planned out so far. I'm still new to this so I could be doing it completely wrong. And it's only five groups. It was more until I condensed it some.
Although I find it weird having so many entities which are different from each other, but I will ignore this and get to the question.
It depends on the group criteria you need, in the case you described where each group has its own columns and information I guess your design is a good one, especially if you need the information in a readable form in the database. If you need all groups in a single table you will have to save the group relevant information in a kind of object, either a blob, XML string or any other form, but then you will lose the ability to filter on these criteria using the database.
In a relational Database I would do it using the design you described.
The design of your tables greatly depends on the requirements of your software.
E.g. your description of users led me in a wrong direction, I was at first thinking about a "normal" user of a software. Basically name, login-information and stuff like that. This I would never split over different tables as it really makes tasks like login, session handling, ... really complicated.
Another point which surprised me, was that you want to store the equipment in columns of those user's tables. Usually the relationship between a person and his equipment is not 1 to 1 and in most cases the amount of different equipment varies. Thus you usually have a relationship between users and their equipment (1:n). Thus you would design an equipment table and there refer to the owner's user id.
But after you have an idea of which data you have in your application and which relationships exist between your data, the design of the tables and so on is rather straitforward.
The good news is, that your data model and database design will develop over time. Try to start with a basic model, covering the majority of your use cases. Then slowly add more use cases / aspects.
As long as you are in the stage of planning and early implementation phasis, it is rather easy to change your database design.