How to create multiple related tables in mysql database - mysql

My title might not really convey what i'm trying to achieve, I have some tables which are related but i can't figure out how to create this relationship to make storing and retrieving data much easy. Below is what i was able to come up with.
color table
colorId(PK)
productId(FK)
colorName
size table
sizeId(PK)
productId(FK)
size
product table
productId(PK)
priceId(FK)
Qty
Name
Title
price table
priceId(PK)
productId(FK)
Now my problem is i have product with different variety for example
Men's blue addidas glide running shoes with productId 1, this product have different sizes and different color and the prices varies on sizes and color. example, if this pair of shoe color BLUE size 11 sells for $50, the same pair of shoe with bigger size and different color say size 12 color red might sell for $55, also this same pair of shoe color blue might have only size 11 available in stock and color blue size 12 of this pair might not be available, how do i create my table to save all the differences between color and sizes, and also prices. Any help on this, thanks

You probably shouldnt have every single attribute in it's own table, a potentially better way would be to have a product table and a variant table. This way you could have price, size, color, quantity available, etc all in the same table, then join on the product i.e. Men's blue adidas glide running shoes.
Your variant table would look something like this:
| variant_id | product_id | price | colour_id | size_id | quantity_available | in_stock |
| 1 | 1 | 50.00 | 1 | 11 | 20 | 1 |
| 2 | 1 | 55.00 | 2 | 12 | 0 | 1 |
Then you could load each variant individually, and have the quantity_available updated whenever you make a sale. I've also included an in_stock boolean so you can override whether stock appears on your site without having to adjust the quantity_available.
You'd then have the variant_id on the purchase table so you can join these later. Also, I like having sizes and colours on their own tables so you can put a taxonomy in place to aggregate all they blues say, or all the XS, S, M, L, XL.
Something like:
| colour_id | name | base_colour_id |
| 1 | Royal Blue | 3 |
| 2 | Spanish Blue | 3 |
| 3 | Blue | 3 |
| 4 | Ultramarine | 3 |
| 5 | Green | 5 |
| 6 | Mint Green | 5 |
This way you can add more unique colour variants and still report on base colours or full colour names. Here you'd use: SELECT * FROM variant_colour a JOIN variant_colour b ON b.colour_id = a.base_colour_id you'd get:
| colour_id | name | base_colour_id | colour_id | name | base_colour_id |
| 1 | Royal Blue | 3 | 3 | Blue | 3 |
| 2 | Spanish Blue | 3 | 3 | Blue | 3 |
| 3 | Blue | 3 | 3 | Blue | 3 |
| 4 | Ultramarine | 3 | 3 | Blue | 3 |
| 5 | Green | 5 | 5 | Green | 5 |
| 6 | Mint Green | 5 | 5 | Green | 5 |
This same idea can be used for sizes etc so you don't end up with hundreds of unique attribute variants that make your info impossible to report on.

Related

Show rows from another tables if exist (SQL)

I want to show data that a user can modify. If the user do changes, i like keeping the original data in my database.
When a user get data, he should view the data modified.
(Much users can modiffied data).
For example:
Products (non editable for users)
ID | Name | Color
----------------------
1 | Apples | Yellow
2 | Pears | Green
3 | Lemons | Yellow
ModProducts (one row for modified product and user)
SourceID | UserID | Name | Color
-------------------------------------------
1 | 3 | RedApples | Red
1 | 4 | Sminth Apples | Green
Result for UserID 3:
ID | Name | Color
-------------------------
1 | RedApples | Red
2 | Pears | Green
3 | Lemons | Yellow
I tryed with COALESCE, CASE but i canĀ“t filter by UserID.
I Also tryed with GROUP BY, putting all data in same table, but I have not managed to give priority to the modified data
I'm going crazy..
Maybe you're designing the data model wrong?
You probably just misplaced the UserID filter. The filter on UserID has to be part of the outer join condition it can not be in the where clause. Try the following select:
select p.id,
coalesce(m.name, p.name) name,
coalesce(m.color, p.color) color
from products p
left join modproducts m on m.id = p.id and
m.userid = 3
Problem solved in one table
Table Products
ID | Ref | UserID | Name | Color
-------------------------------------------
1 | 1 | 0 | Apples | Yellow
2 | 2 | 0 | Strawberrys | Red
3 | 3 | 0 | Lemons | Yellow
4 | 1 | 2 | Apples | Green
5 | 1 | 3 | MiniApples | Green
I like this result
ID | Ref | UserID | Name | Color
-------------------------------------------
4 | 1 | 2 | Apples | Green
2 | 2 | 0 | Strawberrys | Red
3 | 3 | 0 | Lemons | Yellow
I resolv this form:
SELECT *
FROM ( SELECT * FROM Products ORDER BY Ref, UserID DESC) AS Prod
WHERE UserID = 2
OR UserID = 0
GROUP BY Ref

Laravel, Products with Attributes in a many-to-many table

I'm building a platform where Suppliers can add products, and shop owners can 'copy' those products to their shops and sell them.
A Supplier can create products, and he can add all sorts of attributes to them, like the size, colors.
When a Shop wants to use one of the Supplier's products, he can choose which attributes he wants to offer. For example if the Supplier has a T-Shirt in offer with 3 sizes. The shop may choose to sell that T-Shirt with only 2 sizes.
So I have a Products table which looks like this. The Supplier adds products in here.
+----+-------------+-------+
| id | description | price |
+----+-------------+-------+
| 1 | T-Shirt | 10 |
| 2 | Car | 100 |
+----+-------------+-------+
I have a Product attributes table, Which is also filled by the Supplier
+------------+-------------+------------------------------+
| product_id | description | options |
+------------+-------------+------------------------------+
| 1 | size | ["small", "medium", "large"] |
| 1 | color | ["white", "black"] |
+------------+-------------+------------------------------+
Shop Side
When a Shop owner wants a Product. I make a record in the shop_products table, referencing which Shop wants what Product, and adding an optional image, as following
+---------+------------+-----------+
| shop_id | product_id | image |
+---------+------------+-----------+
| 1 | 2 | image.jpg |
| 1 | 3 | image.jpg |
+---------+------------+-----------+
Now the only issue remaining is: How do I make sure the Shop can choose which attributes he wants to take.
Should I create a shop_product_attributes table.. But I can't put a relation on the many-to-many because it doesn't have an id?
If its possible to change your database structure i would do it this way, i know its a bit of a change to what you have but i think you have to think of a product as a relation, this is because though a t-shirt is a product the actual t-shirt black medium is a completely different product to a t-shirt black small and your suppliers will almost certainly referecne them this way
Your products table would look like this but its not your primary table referencing products, this holds the generic stuff that a product will have such as a description
or a name
+----+-------------+-------+-----------+-------------+
| id | name | price | image | description |
+----+-------------+-------+-----------+-------------+
| 1 | Super-T | 10 | image.jpg | some text |
| 2 | Focus | 100 | image.jpg | some text |
+----+-------------+-------+-----------+-------------+
Your primary table would be a sku table think of this as your product, if you have any sku specific stuff you would put them here
+----+-------------+------------+--------------+
| id | sku | product_id | category |
+----+-------------+------------+--------------+
| 1 | p1-cb-m | 1 | t-shirt |
| 2 | p2-cb-s | 2 | t shirt |
+----+-------------+------------+--------------+
Then have a attributes_sku table, this will link the sku to the attribute
+---------------+--------------+
| sku_id | attribute_id |
+---------------+--------------+
| 1 | 1 |
| 1 | 2 |
+---------------+--------------+
Attributes for normalisation
+----+-------------+------------+
| id | type | name |
+----+-------------+------------+
| 1 | color | black |
| 1 | size | medium |
+----+-------------+------------+
Shop Sku table
+---------+------------+
| shop_id | sku_id |
+---------+------------+
| 1 | 1 |
| 1 | 2 |
+---------+------------+
the advantages of this is you can do
foreach $shop->skus where category = t-shirt to display all their t-shirts
then you can do $skus->product->name
$skus->product->attribute->name or better yet set a relationship on the sku model to be say colour $this->attribute->where('type', color);
Note
A small note i'd further normalise this by having a categories and types table, so your attributes type would actually be a type_id that is a belongs relationship to a types table, and your sku category would be a category_id, to a categories table, this is so in the future if you category or type decides to change name you dont have to edit 1000s of records etc
Actually, you can create a many-to-many relation in shop_product_attributes table.
Since your Product Attributes table has a compound key of 2 fields: [product_id,description], your many-to-many relation will have a trinary-key - [shop_id,product_id,description] where [product_id,description] is used as a reference foreign-key as well.

sql many to many relationship with only 2 tables

So I have two tables I need to join for a client. These tables only share 1 field in common (COLOR, and it isn't a unique key ident). Is is possible to join/relate these two tables?
So let's say theoretically I have two tables with COLOR and a COLOR ATTRIBUTE, as follows:
+-------+----------+
| COLOR | NAME |
+-------+----------+
| red | brian |
| red | ben |
| red | tom |
| red | jennifer |
| blue | tom |
| blue | billy |
| blue | michelle |
+-------+----------+
And another table that is ONLY related by the color column, but has multiple color weights:
+-------+--------+
| COLOR | WEIGHT |
+-------+--------+
| red | 12 |
| red | 3 |
| red | 11 |
| blue | 4 |
| blue | 23 |
| blue | 7 |
| blue | 5 |
| blue | 10 |
+-------+--------+
So how can I join these two tables given ONLY the color column is shared? What would the result look like? Thanks in advance!
While color is not a unique identifier, if you plan to perform a join on it, it will be treated as such.
SELECT * FROM Table1 t1
LEFT JOIN Table2 t2
ON t1.COLOR = t2.COLOR
ORDER BY COLOR DESC;
This outputs three columns with 12 "red rows" and 15 "blue rows."

Mysql Swap data between rows using a dummy table [duplicate]

This question already has answers here:
Switch id numbers of two rows in MySql
(5 answers)
Closed 9 years ago.
Suppose a table fruits that looks like this:
------------------------------------------
| id | name | color | calories |
------------------------------------------
| 1 | apple | red | 20 |
| 2 | orange | orange | 10 |
| 3 | grapes | green | 5 |
| 4 | bananas | yellow | 15 |
| 5 | plum | purple | 25 |
------------------------------------------
How can I swap the values of a row, with another, leaving the id number intact?
Example:
SWAP ROW WITH ID "5" WITH ROW WITH ID "2"
Result:
------------------------------------------
| id | name | color | calories |
------------------------------------------
| 1 | apple | red | 20 |
| 2 | plum | purple | 25 |
| 3 | grapes | green | 5 |
| 4 | bananas | yellow | 15 |
| 5 | orange | orange | 10 |
------------------------------------------
Note that all the values are intact except for the id. Note that this is a very large list in reality.
Note: id, and some of the values of the table are unique.
Note2: There's a question posted on this here, but it requires not using a dummy table, so I'd like to see the solution when the table has unique values other than just id.
Thank you
UPDATE fruit a, fruit b
SET a.color = b.color,
a.name = b.name,
a.calories = b.calories
WHERE a.id <> b.id
AND a.id in (2,5)
AND b.id in (2,5);
The following statements will work.
UPDATE fruits SET id=6 where id=2
UPDATE fruits SET id=2 where id=5
UPDATE fruits SET id=5 where id=6

database structure for multiple options on products

I have products in my database (MySQL).
I have my prices based on different combinations of options for my products.
I have the following data:
PRODUCTS
prodID | prodName
1 | Ball
OPTIONS
optionID | optionName | prodID
1 | color | 1
2 | size | 1
3 | material | 1
OPTIONVALUES
ovID | optionID | ovValue
1 | 1 | red
2 | 1 | blue
3 | 2 | small
4 | 2 | big
5 | 3 | wood
6 | 3 | glass
for prices I would like to have like this:
red small wood ball - $13
red small glass ball - 14
red big wood ball - 16
red big glass ball - 17
blue small wood ball - 12.5
[...]
How can I design the database structure for this?
I have tried several ways but none was good. if the number of the options were static then every option could have its own table, but this was that is not a good solution.
I like what you already have. If you want it to be fully flexible as i guess you do, i would do the following:
Add two more Tables.
Product_Instance
instanceID | prodID | price
1 | 1 | 13
Product_Instance_Options
instanceID | ovID
1 | 1
1 | 3
1 | 6
In this way you could define all possible combinations and prices for them. Might be a hell of a lot work to set up all the prices, but if you cant calculate them (like glass = +2$, small=2$ / big=4$) you will have this however you do it.
How about something like this:
productTypes
prodID | prodName
1 | Ball
2 | Car
productInstances
prodInstanceID | prodID | Prize
1 | 1 | $19
2 | 1 | $50
3 | 2 | $8
properties
propertyID | propertyName
1 | color
2 | size
3 | material
propertiesValues
pvID |propertyID | propertyName
1 | 1 | red
2 | 1 | blue
3 | 2 | small
4 | 2 | medium
5 | 2 | large
6 | 3 | wood
7 | 3 | glass
productProperties
ppID | prodInstanceID | pvID
1 | 1 | 1
2 | 1 | 3
3 | 1 | 6
4 | 2 | 2
5 | 2 | 4
6 | 2 | 7
7 | 3 | 1
8 | 3 | 3
9 | 3 | 6
In your design you can't determine which option belongs to which product instance. If you look at your table optionvalues, there is no way to group together your options.