multiple column values in mysql - mysql

I need to make a table 'Movies' which will have columns:
ID Title Description Category etc
And another one called 'Movie_Categories' containing, for example
ID Category
1 Action
2 Adventure
3 Triller
but since category in table Movies will have multiple choices what is the correct way to do this?
should i use comma-separated values like someone said in this post Multiple values in column in MySQL or is there a better way?

This is a many-to-many relationship.
You need a join table to make it right, such as :
CREATE TABLE film_category (
category_id int,
film_id int,
PRIMARY KEY (category_id, film_id)
);

DO NOT GO FOR COMMA-SEPARATED VALUES. NEVER.
Having said that. Bear in mind that when you have a so called many-to-many relationship, that is, a relationship where you can have one category with many movies and one movie with many categories, you will always need to generate an additional table.
This table will only need the Primary Keys of each of the other 2 tables and will have a compound key.
So the schema will end up being:
Movies(ID, Title, Description, Category)
Categories(ID, Category)
Movies_Categories(ID_Movie, ID_Category)
In bold are the primary keys.
In order to get all the categories for a movie you will just have to join each of the three tables.
A final comment about having multi-valued fields is that your table will not be in First Normal Form which will, sooner or later, give you lots of headaches.

The last thing to do is have a non normalized table by storing comma separated values.
*You should have a table movies and a table for categories.
You should create a mapping table which will map the movieId to the categoryId*

Related

how to make a relationship table between 3 table (2 to 1) in SQL

lets say we have 3 table in our database
tables:
table books:
book_id
book_title
...
table magazines:
magazine_id
magazine_title
...
and genres:
genre_id:
genre_name
and now we say want to know what book has what genre and what magazine has what genre, this is the way i know for two table
relation tables:
table book_genres:
genre_id
book_id
table magazine_genre:
genre_id
magazine_id
in this way we have to create several separate table for joining the books, magazine and maybe more tables. and i been told that always have 2 id column in join tables.
but i'm wondering about if i could do something like this
the table that not working!
table title_genres:
genre_id
book_id
magazine_id
...
this is more simple but i get an error when i insert a book genres that says magazine_id can't be empty NULL because its primary key.
its gonna be save me for creating a lot of tables. like if i decide to have a category table then i have to join books and magazine separately.
and my question: is the 2 column thing is a good practice or there is a better way for this?
You use bridge tables to represent m:n relationships. If a book can have many genres and a magazine can have many genres, then you need bridge tables like the book_genres table you are showing.
And if books are very different from magazines in your database, then yes, have separate tables for books and magazines.
This leads to two bridge tables, just as you describe and I see nothing wrong with this.
Your idea to have one bridge table is generally possible, but doesn't solve any problem.
But well, let's see how we would construct such a multi bridge table. First of all you'll want a check constraint ensuring that always exactly one of the columns book_id and magazine_id is filled. Then you want a unique constraint on COALESCE(book_id, magazine_id), genre_id. This would usually be done with a function index, which MySQL doesn't support as far as I know. I suppose though, that you could create a generated column which you can index in MySQL.
And then you want to read the relations as quick as possible. With a bridge table like book_genres you have one row per book and genre and an index to get the relation as quick as possible. With a multi bridge table like title_genres you don't. You have one table containing relations you are interested in and others you are not interested in. You'd want a partial index like
create unique index idx on title_genres (book_id, genre_id) where book_id is not null;
but MySQL doesn't support partial indexes. You could
create unique index idx on title_genres (book_id, genre_id);
which leads to a larger index, but serves the purpose. You'd do the same with
create unique index idx2 on title_genres (magazine_id, genre_id);
And now, with all this work, what have you gained? Your database has become way more complicated than with the simple book_genres and magazine_genres tables. Keep it simple. Use these two tables instead of the multi bridge monster :-)
You can absolutely store the records this way if you have a category field that has information such as (books, magazines etc). So, in other words your table is vertically partitioned by category field but logically it’s a single table.
Only drawback I can see is if this table grows fast then query performance would be a problem because (a) the table will be huge so it will consume more memory even if you are only looking for specific categories and not all of them (b) you always have to use inline sub query since your category filter have to applied every time for every join and when you use inline queries for joins the database would not be able to make use of indexes will be affect the performance of the queries.
Note : You would not be able to store the records in any other way. For example even if a magazine and a book have same genre you have to have them in separate rows and not the same row because if you do that your model will get into other kind of troubles.

what is the best design for the table which have one forign key and the FK has multiple tags and every tags has its own table table

hey i just want to create a table for photo .which has a column that can store multiple type like it belongs to the (wildlife, nature ,adventure..etc) and the tags liks with its own table for the table updation record
You can go ahead keeping 6 columns.
photo_tag_id, photo_tag, photo_links, photo_created_date, photo_updated_date
This table would be unique on photo_tag_id and photo_tag primary indexed on photo_tag_id and secondary indexed on photo_tag columns while storing data in MySql. You can always update based on filter condition of photo_tag_id and photo_tag.
photos:
id,
who, when, where
tags: -- this is a many:many mapping table
photo_id, -- join to photos.id
tag VARCHAR(99)
PRIMARY KEY(tag, photo_id),
INDEX(photo_id, tag)
The column tag could have wildlife, nature, adventure, etc
If, by tag, you mean a category, and a photo is in only one category, then it would be done differently: add category (or category_id) to photos. This is a 1:many relationship.

Is my database rational correct? one Primary key to Multiple foreign keys?

I have an idea that I want to execute and am very rusty on my database design when it comes to the relationships between tables. I want to be able to type in 3 ingredients into 3 <input type="text"> fields and search for all the recipes with those ingredients.
I have 3 tables...
ingredients
recipe
menu
the columns that are bold are my primary keys and i want the columns in italics to be the foreign keys.
Example - iName is the primary key to iName1 iName2 and iName3.
INGREDIENTS
iName - iType
RECIPE
mName - iName1 - iName2 - iName3 - method
MENU
mName - mDiscription - mAllergy
Are the relationships between my tables efficient enough for what I want to do? and what would the join query be if I want to for example
SELECT mName, mDiscripton, mAllergy
FROM menu
WHERE iName1 = input etc etc
I already have a one table version of the database and the query I'm using works fine; I just want to redesign my database and modify my query to suit.
Your design is missing one table to be efficient; remove iName1 to iName3 from your recipe table and add a mapping table "recipe_ingredients" with foreign keys for recipe and one ingredient. You will then have one to many rows in that table for every recipe (look at my example). But: You can easily search for all recipes where an ingredient is used. And you can use 10000 ingredients for one recipe if necessary.
How is the table menu related to recipes? Does a menu always consist of one recipe? Otherwise also add a mapping table for that relation.
SELECT mName, mDiscription, mAllergy
FROM menu
JOIN recipe ON recipe.mName = menu.mName
JOIN recipe_ingredients ON recipe_ingredients.mName = recipe.mName
WHERE recipe_ingredients.iName = 'whatever'
Please don't use 1..n colums to save a n..m connection between two tables.
As you can use one ingredient in different recipes, you will need a matching table.
Those are often called table1_2_table2, or in your case recipe2ingredient.
In there you store the primary keys from both tables (in most cases as a combined primary key on that table, as it often makes sense)
The same should go for menu and recipe, since you could want to use a recipe in several menus.
So
Table 1 - Menu (ID, Name, ... whatever columns you need on top of that)
Table 2 - Recipe (ID, Name, ...whatever columns you could desire)
Table 3 - Menu2Recipe( IdMenu, IdRecipe)
Table 4 - Ingredient (ID, Name, measurement unit)
Table 5 - Ingredient2Recipe( IdRecipe, IdIngredient, Amount )

fastest way to query a field that has more than one possible matching value

I have 2 tables.
First table is called professions, and those are indexed by ID. So each profession now has a unique ID associated with it.
My second table is called contacts, and in there I have a profession field that right now only hold the ID that a certain profession is associated with.
My problem is that what if I have a contact that has more than one profession associated with it.
What would be the best way to query the table and ways to store the professions of a contact. I didn't want to do is create a field to just store a 0 or 1 int for each profession I have. The reason is because I want to dynamically grow the professions table and have the numbers reflect any dynamic changes on my site when I query.
You have a many-to-many relationship. To implement that in MySQL you should use a linking table. So professions and contacts should have an id in each table, but no foreign keys, and you create a new table called profession_contact_links or something, containing its own id, and profession_id and contact_id, which are both foreign keys to the respective tables. Then you can have many contacts linked with each profession, and many professions linked with each contact. To connect the two main tables together in a select you will need two joins, and what they are will depend on what exactly you want to select.
The standard solution to this modelling issue is called a link table.
Basically it is a table that contains the ids of the two tables that are linked, so you would have a link table with to columns and a primary key that is both of those columns:
(profession_id, contact_id)
or the other order... doesn't matter that much, but the order can affect performance, the key you will be searching on most often is the one you want first.
You then use either SELECT ... IN (...) or SELECT ... JOIN ... to query the data that you are after.
Depending on what you want and how you want to find it, i'd suggest rlike or in
SELECT ... FROM <table> WHERE <column name> RLIKE "^id1|id2|id3$"
This will find any cell that contains any of those three terms
or use
SELECT ... FROM <table> Where <column name> IN ('id1','id2','id3')
this will find any cell that is equals to one of those three.

having trouble with foreign key queries

I'm new to SQL and I'm having a hard time figuring out how to execute queries with foreign keys on MySQL Workbench.
In my example, I have three tables: people, places, and people_places.
In people, the primary key is people_id and there's a column called name with someone's name.
In places, the primary key is places_id and there's a column called placename with the name of a place.
People_places is a junction table with three columns: idpeople_places (primary key), people_id (foreign key), and places_id (foreign key). So this table relates a person to a place using their numerical IDs from the other two tables.
Say I want the names of everyone associated with place #3. So the people_places table has those associations by number, and the people table relates those numbers back to the actual names I want.
How would I execute that query?
Try this to find all the people names who are associated with place id 3.
SELECT p.name
FROM people as p
INNER JOIN people_places as pp on pp.people_id = p.people_id
WHERE pp.places_id = 3
OK, so you need to "stitch" all three tables together, yeah?
Something like this:
select people.name
from people -- 1. I like to start with the table(s) that I want data from, and
, people_places -- 2. then the "joining" table(s), and
, places -- 3. finally the table(s) used "just" for filtering.
where people.people_id = people_places.people_id -- join table 1 to table 2
and people_places.place_id = places.place_id -- join table 2 to table 3
and places.name = "BERMUDA" -- restrict rows in table 3
I'm sure you can do the rest.
Cheers. Keith.