Database Class Model - Film - mysql

I'm currently designing a Film database. I currently have a film table with filmtitle, length etc. I then have a actors table. I have a junction table between these with filmid and actorid. This will have all the actors that play a role in the film.The junction table also has a role attribute.
Now, how would I go about showing the star actors in the film (2 or 3 select actors out of the however total in the film) Would I create a separate junction table of staractors with filmid and actorid, but this would be repeating the other already created junction table, or do it in the junction table, but this would mean there would be two actorID's?
[CrudeDrawing(forgot to include role in junction table)]

You have built most of what is required already. Your junction table can be utilized to include a column for whether the actor is start or not (a Boolean column). You could instead use an int column where the values show how much of a star he/she is. You could also add other interesting information in the junction table such as character name, total appearance length, etc. There is no need for an extra table.
Examples:
One the left any number > 0 means a star. 1 means big star, 2 means small star, etc. On the right, 1 means a star. Note the two tables are not necessarily equivalent in this example.

Related

MySQL - Storing IDs as an array in a table

Let's say I have two tables on MySQL 5.7
Film
---
ID
name
location
year
user_id
actors
Actor
---
ID
name
born
location
Then I want to link each actor to a film, so each film entry would have actors as an array like [5, 2, 12] and on.
Now, that's one way, I have been told. Is this the appropriate way? Is this right? Wrong?
If I understand you correctly then:
You have to create a Foreign Key in your actors table which contains the film id. But there you can only take ONE film per actor.
If you create a table BETWEEN these tables you can access both tables and combine them with join. So every actor can take place in more than only one film.
Never save an Array in your Database, because you can't access this array with select commands.
In relational databases instead of storing an array of ids a field, you should store a record for each id in a separate related table.
In this specific case, you can have a Film with many actors, and also each actor of this specific film could also work in other different films, so the relation is many to many.
To model this relation you actually need a third table that would hold the ids of the related actors and films the work in.
Like this:
Film
ID
name
location
year
user_id
Actor
ID
name
born
location
ActorInFilm
ActorID
FilmID
Don't use comma delimited values in a table. Rather than have Actors and Films in the Films table, make another table called film_actors or whatever and if you need a table for actor info make an Actors table as well. Then in film actors make a new entry for each actor in the films. It's much less taxing to search these fewer columns and a simple int than a whole row of other information plus parse commas. A sample of some data from film_actors should look like the following:
film : 1, actor : 2 ,
film : 1, actor : 4,
film : 2, actor : 2
Searching through csv columns is a lot more taxing than doing a search of all films where film = x and actor = y.
You can use MySql JSON field to store arrays or lists that can still be indexed, queried by the DB engine.

Design database for 1 to 1 relationship when some columns are applicable only in certain cases

I have a users table which stores the details of two types of users namely students and teachers. There are 10 fields like username, password etc common to both students and teachers. There are no 1 to n relations in case of any data here.
In case of students, I have to store twenty different 1 to 1 data like weight, DOB, Admission No., Parent,Phone number etc.
In case of teachers, I have to store a separate set of twenty 1 to 1 data like email id, affiliation number etc which is not related to students in any way.
What is the best database structure I can use in this scenario from below? If there are better options please provide that too.
One table with 50 columns where 20 columns will have NULL in case of students and 20 columns will have NULL in case of teachers
One table with 30 columns where first 10 columns stores common data and next 20 columns store students details in case of student and teacher's data in case of teacher.
Two tables one with 10 column to store user details. And another table with 20 columns to store students details in case of student and teacher's data in case of teacher.
Three tables one with 10 column to store user details. Another table with 20 columns to store students details and yet another table with 20 columns to store teacher's data
Single Table Inheritance and Class Table Inheritance are both fine. In fact Fowler has recommended STI for agile. And if you use a good ORM like Hibernate, the difference is trivial. If you use PostgreSQL your nulls won't take up any extra space either.
That being said, you should further normalize your tables (parents phone #s should be in a diff table for example). See https://dba.stackexchange.com/questions/12991/ready-to-use-database-models-example/23831#23831 for some help
You have to remember the principles of relational design. All the columns should be dependent on the key fields and only on the key fields.
Its better to have choice 4 tables:
1) For a base person details (columns teachers and students both have).
2) A teacher table for details that pertain to only teachers. This will relate to base person table with a foreign key (just like table 3).
3) A student table for details that pertain to only students.
No extra empty columns and very flexible in the kind of queries (some of which that you are not anticipating) you will be able to do.
the First thing I thought of was a pigs ear relationship, a link entity so that you could have ID, teacherID, studentID to show which teachers teach which students, but then I realised this isn't what you asked for so...
Why not just have a single boolean, true if teacher, false if not?
Look up these two tags: single-table-inheritance class-table-inheritance
These correspond to well known techniques that are like option 1 and option 4. There are situations where one or the other of these is best. The tag wikis (info) and the questions grouped under the tags will give you some additional help.

Mysql tables link with each other

I will create 3 tables in mysql:
Movies: id-name-country
Tv-Series: id-name-country
Artists: id-name-country
Instead of entering country information into these tables seperately, i am planning to create another table:
Countries: id-country
And i will make my first three tables take country data from Countries table. (So that, if the name of one country is misspelled, it will be easy just to correct in one place. Data in other tables will be updated automatically.
Can i do this with "foreign keys"?
Is this the correct approach?
Your approach so far is correct, ONLY IF by "country" in Tv-Series and Artist you mean country ID and NOT a value. And yes you can use foreign keys (country id in tv-series and artist is a foreign key linking to Countries);
Edit:
Side note: looking at your edit I feel obliged to point out that If you are planning to link Movie/TV-Show with artist you need a 4th table to maintain normalization you've got so far.
Edit2:
The usual way to decide whether you need tables is to check what kind of connection 2 tables or values have.
If it's 1 to many (like artist to country of origin), you are fine.
If you have Many to many, like Movie with Artist where 1 artist can be in multiple movies and 1 movie can have multiple artists you need a linking table.
If you have 1 to 1 relation (like customer_ID and passport details in a banking system, where they could be stored separately in customer and Passport tables, but joining them makes more sense because a banks only hold details of 1 valid passport for each customer and 1 passport can only be used by 1 person) you can merge the tables (at the risk of not meeting Normalization 3 criteria)

Mysql: is it better to split tables if possible?

To make you understand my question I'll give you an example:
I have a chat web app with many rooms, let's say 5 rooms.
People can choose to stay only in one room and they choose it at login.
When they choose the room I have to retrieve the people already in the room, so I can structure my db in two ways:
each room one table with the people being records;
all the rooms in one table, people are the records and a column indicating the room they are in;
In the first case the query would be:
SELECT * FROM 'room_2' WHERE 1
In the second case the query would be:
SELECT * FROM 'rooms' WHERE room = 'room_2'
Which is the best?
I think the only parameter to consider is performance, right?
In this example, no, because people are all 'like' objects and should therefore be in the same table.
All people and rooms in one table with a primary key on people, in this simple example.
Table Rooms(pk_person, personName, table_id)
But I want to talk about a structure that you will want to consider as your website grows. You’ll want three tables, one for each object (chat rooms, people) and one for the relationships.
Chat_Rooms(pk_ChatId, ChatName, MaxOccupants, other unique attributes of a chat room)
People(pk_PersonID, FirstName, LastName, other unique attributes of a person)
Room_People_Join(pk_JoinId, fk_ChatId, fk_PersonID, EnterDateTime, ExitDateTime)
This is a “highly normalized” structure. Each table is a collection of like objects, the join allows for many to many relationships, and object rows are not duplicated. So, a Person with all their attributes (name, gender, age) is never duplicated in the person table. Also, the person table never defines which chat rooms a person is in, because a person could be in one, many, none, or may have entered and exit multiple times. The same concept applies to a chat room. A chat rooms features, such as background color, max occupants, etc. have nothing to do with people.
The Room_People_Join is the important one. This has a unique primary key for which chat rooms a person is in and when they were there. This table grows indefinitely, but it tracks usage. Including the relationship table is what logically normalizes your database.
So how do you know which users are currently in chat room 1? You join your people and rooms to the join table with their respective Primary and Foreign keys in your FROM clause, ask for the columns you want in your SELECT clause, and filter for chat room 1 and people who haven’t yet left.
SELECT p.FirstName, p.LastName, r.ChatName
FROM Room_People_Join j
JOIN People p ON j.fk_PersonID = p.pk_PersonID
JOIN Chat_Rooms r ON j.fk_ChatId = r.pk_ChatId
WHERE r.ExitDateTime IS NOT NULL
AND pk_ChatId = 1
Sorry that’s long winded, but I extrapolated your question for database growth.
The answer is very simple and strongly recommended - one database table for all rooms for sure! What if you will later like to create rooms dynamically!? For sure you would not create new tables dynamically.

Creating a relationship between three tables

There are many ways I can think of to hack this together, but I want to know what the best practice is here:
I have three tables. Products, Pricelists and Prices.
One product can belong to many pricelists.
One pricelist can belong to many products.
This is a many to many relationship and as far as I know requires a Junction table (pricelist_products). Which works well.
Now, one product within a pricelist can have multiple prices. A product is only ever given a price once its within a pricelist.
What I've thought about here is using the ID from the junction table 'pricelist_products' as a foreign key within the prices table, but this feels really.... hacky?
Fishy example:
Product 1 - Fishing Rod.
Pricelist A - Fishermen.
Pricelist B - Fishingshop.
Pricelist A, Product 1, price 1:
(Monthly repayments option 1 (no deposit))
Pricelist A, Product 1, price 2:
(Monthly repayments option 2 (with deposit))
Pricelist A, Product 1, price 3:
(Quaterly repayments)
Pricelist B, Product 1, price 1:
(Quaterly repayments)
What I've thought about here is using the ID from the junction table 'pricelist_products' as a foreign key within the prices table, but this feels really.... hacky?
Maybe the issue here is just one of perspective. The purpose of the junction table is to uniquely define each combination within your many-to-many relationship (initially: pricelist to product). This can be achieved in the junction table with the fields product_id and pricelist_id alone, and without the surrogate key id.
Of course, if you defined your junction table with PRIMARY KEY (product_id, pricelist_id), this table would lack the ability to uniquely define combinations when price is considered. So you add a third id to the junction table. It appears you were looking at this field as a necessary surrogate key when defining a relationship between only two tables. However, since the real utility of this field relates to the third table, you might name it price_id instead, name your junction table pricelist_product_price, and define the primary key on all three fields (for example). This more clearly demonstrates the purpose of each field, and so may not feel "hacky" in practice.
I don't know if this is a best practice for database design, but keep in mind that there is no reason you must fully normalize every database. You want good performance with reasonable amount of flexibility and scalability (this can mean one thing for a casual blog, and quite another thing for a small business), and that can often be achieved with some degree of non-normalized design.
Edited to add: Okay, there is one other change I forgot to mention that would fall under "good" design or best practices. In your picture, you have two ID fields in the price table where one would be sufficient. As #Gilbert Le Blanc pointed out, you should try to avoid ambiguous field names like having multiple id fields, even if they are in different tables. This will help you see the utility of your fields, identify natural keys, and eliminate redundancies.
If you would not use anywhere else the relation between products and price lists but for prices then an alternative design is like this:
-Table products with fields: id, others
-Table pricelists with fields: id, others
-Table prices with fields: id (autoincrement), product_id, pricelist_id, price
and you would define index (not unique) on the pair of fields product_id, pricelist_id