Mysql database design multiple values for multiple values - mysql

Sorry for my ignorance about mysql and databases, but I'm kind of learning it.
So, suppose the following situation:
I have a table with definitions (ball_definitions) of balls of different colors:
id color
1 red
2 blue
3 green
...
N
where id is the primary value.
and I have a second table (persons) with definitions of persons:
id name
1 John
2 Peter
3 Michel
...
M
(where id is the primary key)
Now, I want to relate to each person, the amount of owned balls by that persons, conceptually, something like this:
john: 1 red ball, 3 green ball, 0 blue ball
peter: 3 red ball, 2 green ball, 1 blue ball.
...
In such a way that both the M and N can vary (for portability reasons).
My first tough was to let persons' table to have N columns where each column was referring to each color, but that is not portable (requires triggers of each change on the ball_definitions change, and it seems quite hard to query).
On the other hand, creating a new table with a "ManyToMany" relation:
persons_id ball_definitions_id amount
1 1 1
1 2 3
1 3 0
2 1 3
2 2 2
2 3 1
seemed to me a little effort when either the number of persons or the number of balls change.
Is there any better solution?
Cheers,
Jorge

No, there is no better solution.
When you have two tables that have an N to N (many to many) relationship you should use an intermediary table.
The alternative would be to create a column in the persons table for every type of ball, or create a column in the balls table for every person which is more effort than the solution you are describing. If you need to add more balls or persons, things get very complicated and messy. You described the best solution.

Related

MySQL does not apply one-to-many relationship

I have the 2 dimension tables and 1 fact table. They look like this:
Dimension table 1: Investor_DM
Investor_nr
Investor_name
1
Jack
2
Kelly
Dimension table 2: Company_DM
Company_nr
Company_name
1
Apple
2
Microsoft
Fact table: Positions
Company_nr
Investor_nr
InvestmentDate
InvestmentSize
1
1
2022-jan-02
$1,000
2
1
2022-feb-03
$1,500
1
2
2022-jun-02
$7,000
2
2
2022-jul-03
$7,500
I assigned Investor_nr and Company_nr as PK's in their respective dimension tables, and assigned FK's in the fact table in which I refer to the PK's.
What I want is when I look for data WHERE Investor_nr = '1', I only get the investments in the fact table of investor 1, etc. However, I still get all investments even though I have created one-to-many relationships between the tables. Same goes for the company dimension table.
This is my
SELECT *
FROM Positions
WHERE Investor_nr = '1'
;
query:
I would hope that if I SELECT * from all 3 tables, the Investor_nr's on each row correspond between the fact and dimension table, but this is not the case. Same goes for Company_nr.
What am I missing here? Am I using the wrong query, or are my relationships wrong?
I tried multiple queries, sometimes only on 1 table and sometimes 2 or 3 tables, but I always get data from investors I did not filter on.
Thanks!

MySQL - How to store multiple combinations of colors for one product?

I am searching for the best solution for the following issue:
I have three tables:
Product
id
productName
1
Tshirt
2
Pullover
3
Jacket
Base Color
id
baseColorName
allowedExtraColorIds
1
Green
1,2
2
Blue
2,3
3
Red
3
Extra Color
id
extraColorName
1
Purple
2
Orange
3
Black
So as you can see, there is a dependency between the tables Base and Extra Color.
So not each Extra Color can be used with each Base Color. For the Base Color "Green" only the Extra Colors with the Ids "1 and 2" are allowed to pick.
Now the Table Product contains the products. However I now want to have a form where the user can first select the product and then he can map combinations of Base and Extra Colors to this product.
Example:
The user selects the "Tshirt" as a product
Now he creates Combinations:
He selects the Base Color "Green" and he selects the allowed Extra Color "Purple"
He selects the Base Color "Red" and he selects the allowed Extra Color "Black"
And now I am wondering how to save this information, so the mapping of the different combinations of Base and Extra Colors for the single product in a MySql Database.
Has anyone an idea how to achieve this? :)
You have to create tables like below to store generated combinations.
selected_products
id
product_id
user_id
1
1
1
2
2
1
selected_product_combinations
id
selected_product_id
base_color_id
extra_color_id
1
1
1
1
2
1
3
3
Here, selected_product_id is a foreign-key reference to the primary key of selected_products table.
Elaborating a bit on what #RiggsFolly already suggested:
work with 1 table of colors. Having two of them will only complexify the situation
create a table where all possible combinations are listed as individual items - you could even consider adding the product to allow scenarios where not all colors are available for all products.
Like this
Product
Basecolor
Extracolor
1
1
1
1
1
2
That way, all checks become a simple singleton query that either gives a result (combination allowed) or doesn't (combination not allowed)
This will change your approach a bit but as said, that's how you do things with RDBMS's. It will save you a lot of headaches afterwards.
Yes, to propose all possible combinations you will retrieve a result set instead of one record, but that is easily solved.

1NF, 2NF, AND 3NF Normalization?

I have a teacher who doesn't like to explain to the class but loves putting up review questions for upcoming tests. Can anyone explain the image above? My main concern in the red underline which shows that supplier and supplierPhone are repeated values. I thought that repeated values occurred when there were many occurrences of the same item in a column.
Another question I have is that if the Supplier is a repeating value, why isnt Part_Name a repeating value because they both have 2 items with same names in their columns.
Example:
It's repeated because the result of the tuple is always the same. E.g. ABC Plastics will always have the same phone number, therefore having 2 rows with ABC Plastics means that we have redundant information in the phone number.
Part1 Company1 12341234
Part2 Company1 12341234
We could represent the same information with:
Part1 Company1
Part2 Company1
And
Company1 12341234.
Therefore having two rows with the same phone number is redundant.
This should answer your second question as well.
Essentially you're looking for tuples such that given the tuple (X, Y) exists, if there exists another tuple (X, Y') then Y' = Y
Looks like five tables to me.
model (entity)
modelid description price
1 Laserjet 423.56
1 256 Colour 89.99
part (entity)
partid name
PF123 Paper Spool
LC423 Laserjet cartridge
MT123 Power supply
etc
bill_of_materials (many to many relationship model >--< part )
modelid partid qty
1 PF123 2
1 LC423 4
1 MT123 1
2 MT123 2
supplier (entity)
supplier_id phone name
1 416-234-2342 ABC Plastics
2 905.. Jetson Carbons
3 767... ACME Power Supply
etc.
part_supplier (many to many relationship part >--< supplier )
part_id supplier_id
PF123 1
LC423 2
MT123 3
etc.
You have one row in model, part, supplier for each distinct entity
You have rows in bill_of_materials for each part that goes into each model.
You have a row in part_supplier for each supplier that can furnish each part. Notice that more than one part can come from one supplier, and more than one supplier can furnish each part. That's a many-to-many relationship.
The trick: Figure out what physical things you have in your application domain. Then make a table for each one. Then figure out how they relate to each other (that's what makes it relational.)

Database design for a tv series app

I'm developing a web application about TV shows. And i need help with the database design.
I made a list of what i need, but i can't figure out how to design it. I have the basic tables. Series, episodes, seasons etc. What i can't do is how to relate people with episodes/series. Here is my list:
There should be multiple people type. Actor/director/writer/guest etc.
I don't think creating seperate table for each type is a good idea. So there should be one people table. And i need to store the type somewhere.
A person may be in 1 or many series.
This can be done with people_serie table with foreign keys to people and series tables. But i need a way to relate a person to episodes too.
An actor may play 1 or many roles.
This can be done with person_role table.
This is where its getting complicating.
A role may be in 1 or many episodes in a serie.
A person may belong to more than one type in a serie. Ex: actor AND director
I hope i make it clear what the problem is.
Well, you're correct not to split the People table.
the first thing to do is add a Roles table, that will contain role id and role title (each column should be unique - you don't want 2 different ids for the Actor role...)
TblRoles
RoleId RoleTitle
-------------------
1 Director
2 Writer
3 Actor
Then you add a PersonToSeries table, that will hold it's own id, the person's id and the series's id.
This table will hold every person ever working on that series, being a regular staff member or a 1 episode guest.
TblPersonToSeries
PTSId PersonId SeriesId
---------------------------
1 1 1
2 3 8
3 4 7
The next table you will need is a PersonToEpisode table, that will hold the PersonToSeries id and the episode id, and the role id.
In this table you only need to keep integer ids so it's very light weight, and you will specify for each record in PersonToSeries the episodes it is relevant for.
TblPersonToEpisode
PTEPTSId RoleId
-------------------
1 2
2 3
3 1
When a person is usually the director of a series, but makes a guess appearance in an episode of that series, you can simply add 2 rows in PersonToEpisode for that PersonToEpisode with a different role id. (one for Actor and one for Director)
TblPersonToEpisode
PTEPTSId RoleId
-------------------
13 1
13 2

Relational Database Design (MySQL)

I have a table User that stores user information - such as name, date of birth, locations, etc.
I have also created a link table called User_Options - for the purpose of storing multi-value attributes - this basically stores the checkbox selections.
I have a front-end form for the user to fill in and create their user profile. Here are the tables I have created to generate the checkbox options:
Table User_Attributes
=====================
id attribute_name
---------------------
1 Hobbies
2 Music
Table User_Attribute_Options
======================================
id user_attribute_id option_name
--------------------------------------
1 1 Reading
2 1 Sports
3 1 Travelling
4 2 Rock
5 2 Pop
6 2 Dance
So, on the front-end form there are two sets of checkbox options - one set for Hobbies and one set for Music.
And here are the User tables:
Table User
========================
id name age
------------------------
1 John 25
2 Mark 32
Table User_Options
==================================================
id user_id user_attribute_id value
--------------------------------------------------
1 1 1 1
2 1 1 2
3 1 2 4
4 1 2 5
5 2 1 2
6 2 2 4
(in the above table 'user_attribute_id' is the ID of the parent attribute and 'value' is the ID of the attribute option).
So I'm not sure that I've done all this correctly, or efficiently. I know there is a method of storing hierarchical data in the same table but I prefer to keep things separate.
My main concern is with the User_Options table - the idea behind this is that there only needs to be one link table that stores multi-value attributes, rather than have a table for each and every multi-value attribute.
The only thing I can see that I'd change is that in the association table, User_Options, you have an id that doesn't seem to serve a purpose. The primary key for that table would be all three columns, and I don't think you'd be referring to the options a user has by an id--you'd be getting them by user_id/user_attribute_id. For example, give me all the user options where user is 1 and user attribute id is 2. Having those records uniquely keyed with an additional field seems extraneous.
I think otherwise the general shape of the tables and their relationships looks right to me.
There's nothing wrong with how you've done it.
It's possible to make things more extensible at the price of more linked table references (and in the composition of your queries). It's also possible to make things flatter, and less extensible and flexible, but your queries will be faster.
But, as is usually the case, there's more than one way to do it.