MySQL - Storing IDs as an array in a table - mysql

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.

Related

MySQL Querying a movie database

I'm very new to SQL, so please bear with me.
I've built a movie database and I'm trying to query it so that all my tables display properly.
I have a movies table with the columns movieID, title, releaseYear, directorID, genreID, and actorID.
Inside the table director, I have directorID and Director.
Using the query SELECT * FROM movies INNER JOIN director ON director.directorID = movies.directorID;, I'm able to get everything in tables movies and director to display (which isn't exactly what I want, but it's in the right track).
My remaining tables are actor, (with actorID and actor's names) starring (with starringID, movieID, and actorID), genre (with genreID and 22 different genres), and moviegenres (with moviegenresID, moviesID, and genreID).
I'm a bit lost and I apologize if this is confusing and messy, but I'm thinking I need to query the database so that all the tables show the data and are associated with the correct column. For example, most movies have multiple genres and actors, which is why I separated them into tables of their own.
I can't figure out how to query everything to display properly in the result grid.
Thanks in advance

SQL - How to insert records that has multiple values of the same column?

I'm creating a database based on Pokemon but I'm currently stumped on inserting Pokemon with different moves.
Each Pokemon has a move set, so not just one move, but many. However, as I attempt to insert the Pokemon with its variable-length amount of moves into the table, MySQL ignores the previous ones and only inserts the last move.
In short: how do I insert multiple records of the same Pokemon but with its different move?
[I guess a good similar real-world example would be a Person having multiple email addresses. How would I go about inserting that into a table?]
The problem is that you're implementing it as a one-to-one relationship, but what you have is a many-to-many relationship (each Pokemon has many moves, each move can be learned by many pokemon).
What you'd probably want to do is have 2 tables.
Table 1: Pokemon
ID, Name, Move1ID, Move2ID, Move3ID, Move4ID, Types etc.
Table 2: Moves
ID, Name, PP, Power, type etc.
Then you could use another table which contains all the join information between those 2 tables. You'd have multiple rows containing the same Pokemon ID and multiple rows containing the same Move ID, but the [Pokemon ID, Move ID] combination would be unique.
Table 3: PokemonMoves
PkID, MoveID
Then you could just do a join from the Pokemon table to the Moves table via this relationship table
SELECT *
FROM Pokemon AS p
LEFT JOIN PokemonMoves AS pm on p.ID = pm.PkID
LEFT JOIN Moves AS m ON m.ID = pm.MoveID
There are lots of posts on SO about many-to-many relationships, this looks like a good place to start: Many to many relationship?
Well, what do the tables look like? (and is their structure under your control?)
If you are constrained to a single "Email" field, the only way I see you can associate multiple email addresses with a single record(=person) is to treat the Email field as a comma (or whatever) delimited list.
If you control the structure however, you can switch to a one-to-many relationship between "Person"s and "Email"s - something like:
tblPerson
[id]
tblEmailAddresses
[person_id]
[email]
You'd query that like this:
SELECT id, email
FROM tblPerson INNER JOIN tblEmailAddresses ON
id = person_id
WHERE id = <person you're interested in>
Which would return as many records as that person has email addresses.
Hard to say exactly how the insert would look without seeing your code/data, but you could do something like:
sID = <whatever>
For each sEmail in EmailCollection
INSERT INTO tblEmailAddresses
(person_id, email)
VALUES (sID, sEmail)
Next

Database Class Model - Film

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.

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 Database column having multiple values

I had a question about whether or not my implementation idea is easy to work with/write queries for.
I currently have a database with multiple columns. Most of the columns are the same thing (items, but split into item 1, item 2, item 3 etc).
So I have currently in my database ID, Name, Item 1, Item 2 ..... Item 10.
I want to condense this into ID, Name, Item.
But what I want item to have is to store multiple values as different rows. I.e.
ID = One Name = Hello Item = This
That
There
Kind of like the format it looks like. Is this a good idea and how exactly would I go about doing this? I will be using no numbers in the database and all of the information will be static and will never change.
Can I do this using 1 database table (and would it be easy to match items of one ID to another ID), or would I need to create 2 tables and link them?
If so how exactly would I create 2 tables and make them relational?
Any ideas on how to implement this? Thanks!
This is a classical type of denormalized data base. Denormalization sometimes makes certain operations more efficient, but more often leads to inefficiencies. (For example, if one of your write queries was to change the name associated with an id, you would have to change many rows instead of a single one.) Denormalization should only be done for specific reasons after a fully normalized data base has been designed. In your example, a normalized data base design would be:
table_1: ID (key), Name
table_2: ID (foreign key mapped to table_1.ID), Item
You're talking about a denormalized table, which SQL databases have a difficult time dealing with. Your Item field is said to have a many-to-one relationship to the other fields. The correct things to do is to make two tables. The typical example is an album and songs. Songs have a many-to-one relationship to albums, so you could structure your ables like this:
Table Album
album_id [Primary Key]
Title
Artist
Table Song
song_id [Primary Key]
album_id [Foreign Key album.album_id]
Title
Often this example is given with a third table Artist, and you could substitute the Artist field for an artist_id field which is a Foreign Key to an Artist table's artist_id.
Of course, in reality songs, albums, and artists are more complex. One song can be on multiple albums, multiple artists can be on one album, there are multiple versions of the same song, and there are even some songs which have no album release at all.
Example:
Album
album_id Title Artist
1 White Beatles
2 Black Metallica
Song
song_id album_id Title
1 2 Enter Sandman
2 1 Back in the USSR
3 2 Sad but True
4 2 Nothing Else Matters
5 1 Helter Skelter
To query this you just do a JOIN:
SELECT * FROM Album INNER JOIN Song ON Album.album_id = Song.album_id
I don't think one table really makes sense in this case. Instead you can do:
Main Table:
ID
Name
Item Table:
ID
Item #
Item Value
Main_ID = Main Table.ID
Then when you do queries you can do a simple join