Tables structure for shop - items - prices - php

Suppose I have 15 shops, 4 products and custom prices for each shop:
each shop doesn't have all the 4 products but can have only 2, or 3 or 4 or even 1.
the prices are similar but customized to each shop. The prices change every 2-3 weeks in all shops, often simultaneously but not always.
the database must contain the historical of the prices.
This is my idea but I'm sure it lacks in the products section:
TABLE1
id | shop_name | product_1 | product_2 | product_3 | product_4
1 shop1 name2 name4 NULL NULL
2 shop2 name1 name3 name4 NULL
TABLE2
id | shop_name | active_from | active_to | name1 | name2 | name3 | name4
1 shop1 2014-01-05 2014-02-07 NULL price NULL price
2 shop2 2014-01-07 2014-02-05 price NULL price price
3 shop2 2014-02-06 NULL price NULL price price
4 shop1 2014-02-08 NULL NULL price NULL price
To get the data of the current prices I could select the rows where active_to is NULL and JOIN the tables to connect table1 with table 2.
To create an istorical chart or table I'll use the between active_from and active_to method.
But I'm limited to 4 products, what if they increase in the future?

I would try the following:
A table that contains the presence of each product in each shop and its price.
shop_id | product_id | price
1 | 1 | 10.23
1 | 2 | 13.51
1 | 3 | 324.12
2 | 1 | 13.20
2 | 3 | 9.80
In this example you see that shop 1 sells products 1, 2 and 3, while shop 2 sells products 1 and 3 only. This is the simple way to do it. It would be better, maybe, to use a table for storing which products are sold in which shops and another table for the prices, since they are different concepts.
Then another table for storing all the changes that have been made to the prices. With this table you can trace back all the price history.
shop_id | product_id | date
1 | 1 | 10.23
1 | 1 | 10.08
... | ... | ...
Whatever solution you take, do not create a column for each product unless you have some strange and very strong reason to do it.

Related

Get data from three tables with library-table between

I have tree tables:
table user_products
user_id | product_specific_id | order_no
1 | 1 | 1
1 | 2 | 1
1 | 3 | 2
table products_library
product_specific_id | product_id
1 | 3
2 | 3
3 | 1
table product_names
product_id | name
1 | prod1
2 | prod2
3 | prod3
Every product in the database does have unique product_id. But when user does order any product, he can modify it, so I created product_specific_id that I'm using in user_products, and table products_library where I can translate every unique product_specific_id to the base product_id.
Now every product_specific_id does have name of related product_id, that I do store in table product_names.
Now I need to display the name of every product_specific_id for specific user_idand order_no.
Expected result should look like this:
user_id | order_no | product_specific_id | name
1 | 1 | 1 | prod3
1 | 1 | 2 | prod3
I'm able to fit in two queries: first I'm selecting list of product_specific_id from user_products, and than I'm nesting SELECT like
SELECT name
FROM product_names
WHERE product_id IN (SELECT product_id
FROM products_library
WHERE product_specific_id IN (...)
But is it possible to fit everything it in one query? I have no idea how such thing could be achieved, if at all. Also, I'm not sure if nesting queries like this is good or not in the first place. Perhaps is it just fine to get it in two queries and nesting queries too much is bad idea?
You can try the below way using just JOIN
select user_id,order_no,u.product_specific_id,name
from user_products u join products_library p on u.product_specific_id=p.product_specific_id
join product_names pn on p.product_id=pn.product_id
where user_id=1 and order_no=1

Relational database with multiple preferences and categories

I'm trying to wrap my head around designing my database which will store one or more preferences for many categories for each user. So in other words, each user can select one or more options from the Colors category, one or more options from the Shapes category, and so on.
My initial thought was to first have a User table with generic user information. Next, there would be a table to store all the different categories as so:
CATEGORY_ID | CATEGORY_VALUE
--------------------------------
1 | Colors
2 | Shapes
3 | Sizes
I'd separate each Category into it's own table (Colors for example):
OPTION_ID | OPTION_VALUE
------------------------------
1 | Red
2 | Blue
3 | Green
Finally, I would have a User Preferences table:
USER_ID | CATEGORY_ID | OPTION_ID
----------------------------------------
1 | 1 | 2
1 | 1 | 3
1 | 3 | 2
2 | 1 | 3
Am I on the right track here or is there a better/more efficient way to designing this. I will be setting up a search results page which will allow visitors to filter through these different categories.
Thanks!

how to implement same product of different weights

I don't know if this question should be here or not but i don't see any other place fit to ask my problem.
See, i am developing an online food portal which obviously sells food , snacks ,cakes and desserts.The real deal comes up when i have to sell a cake which can exist in various weights such as 0.1|0.5|0.9|...4.5 and every one of them costs different.Furthermore, every one of them are present in different quantities in warehouse.
My solution to achieve this was to provide a different row for every variant
ID | product_code | product name | Quantity | price | weight | company_id
1 | 12345 | beer cake | 34 |345 |0.5 |343434defee
2 | 12345 | beer cake | 343 |600 |1.0 |343434defee
3 | 12345 | beer cake | 4 |845 |1.5 |343434defee
4 | 12346 | vodka cake | 341 |345 |0.5 |343434deereee
Here , i looked every product to be a different product,I provided the relation using product code while to differentitate every row , i choose id,product_code as the primary key.
But, using this method involves redudancy as well, every row is looked as a different product.So if i were to display them using php it would show them as different product.
Something like this,
How do i change my structure of my database in order to achieve a single product but with different variants option on the same item?
I could use a php solution , if it's there.
Regards,
BOTjr.
Split the table into two with product_code as foreign key.
Table One
ID | product_code | product name | company_id
1 | 12345 | beer cake |343434defee
2 | 12346 | vodka cake |343434deereee
Table Two
Product_code |Quantity | price | weight
12345 | 34 |345 |0.5
12345 | 343 |600 |1.0
12345 | 4 |845 |1.5
12346 | 341 |345 |0.5
Use Table One to display items, Use Table Two is product description page to select the right quantity

Update tables in database from tables in a different form

I have one working import xml to my mysql, which import to tables.
Now I want to update with these imported tables my new tables. But I don't know how.
The importer import from 3 different xml.
products, price, stock
It's import to products, product_descriptions, images, etc
Example:
Products
ID | Name | stock | date
1 | product 1 | 9999 | 2013.07.13
2 | product 2 | ....
Product_description
ID | description | price | date | sale price
1 | product 1... | 1$ | 2013.07.17 | 0$
2 | Product 2 is blabla.. | 999 $ | 2013... | 10$
I want to update with these items my another tables:
posts
Post ID | post title | description | product ID
100 | products-name | product_description-description | product-ID <- with these item from another tables.
and,
postmeta
post id | meta | value
100 | price | products_description - price
100 | sale price | product_description - sale price
100 | title | products-name
100 | image | imagepath
I don't know how can I do this.
Anyone help me?
You can use INSERT INTO ... SELECT construction.
There is a nice manual from MySQL: http://dev.mysql.com/doc/refman/5.0/en/insert-select.html
For instance,
INSERT INTO posts (post_title, description)
SELECT
Products.Name, Products.stock
FROM Products
This will insert to the posts table all names & stock levels of your products in a title and description columns
P.S. I do not see any connection between Products and Product Description. Are there any foreign keys?

Mapping products with similar names

I am trying to find a good solution to accomplish the following:
I have a table which includes the name of various products, such as:
"Tide - Original Scent".
In addition, I also have the amount in there for e.g. 50 fl oz.
The problem I have right now is, that the product not only comes in containers of 50 fl oz but also in different sizes such as 75 fl oz and 100 fl oz. For each of these I have new rows in the product table:
id| productName | amount | unit
1 |"Tide - Original Scent" | 50 | "fl oz"
2 |"Tide - Original Scent" | 75 | "fl oz"
3 |"Tide - Original Scent" | 100 | "fl oz"
Now I have a web interface to perform a search on this table and whenever I search for "tide" I get all three rows - which is supposed to be like that of course. However I would like a different behavior and this is where I need your help:
Instead of returning all three rows I would like one row only. I would then need to be able to process it in php so that if the user clicks on "Tide - Original Scent" that the user is then prompted to select the size.
To add even more complexity to the task:
I also have products in the same table named:
"Tide - Mountain Spring".
In this case, it would be great to have some relations set up so I know that "Tide - Original Scent" is linked with "Tide - Mountain Spring". Within php I would then like to not only give the user the choice of selecting the size but also the (in this case) scent.
What would your recommendation be on how I can accomplish this (not the php part)?
How would your database look like?
Do I need to create a table where I map these products? How would this look like if you would create this :)
2 possibilities:
Don't store the sizes in that table - along with the other specific information. Move that to another table. Denormalize your structure.
or
Query but group by the name. For the size column, do a count(amount). If it's more than one, you can then populate a drop down with choices. This is good temporary fix.
SELECT productName, count(amount) AS numOfChoices FROM YOUR_TABLE
WHERE LOWER(productName) LIKE 'tide%'
GROUP BY productName
then after the choice is made
SELECT id, amount FROM YOUR_TABLE
WHERE id = "$selectedId"
to present a choice of sizes that will pin point which one.
I would personally setup my tables like this..
Products Table:
ID| Product ID | Product Name | Description
1 | 0404888282 | Tide - Original Scent | Smells Good
Quantity Table:
ID| Product ID | Size| Price | Quantity
1 | 0404888282 | 50 | 4.99 | 23
2 | 0404888282 | 75 | 5.99 | 120
3 | 0404888282 | 100 | 7.99 | 10
This structure you have a table for each unique item, another for the sizes and quantity of each size. Keeps the structure clean and easy to understand.
"Instead of returning all three rows I would like one row only."
SELECT DISTINCT productName FROM YOUR_TABLE WHERE LOWER(productName) LIKE 'tide%'
And you'll need a functional index on LOWER(productName) for good performance. Alternatively a case-insensitive collation sequence could be used on DBMSes that support that (e.g. MS SQL Server).
"I would then need to be able to process it in php so that if the user clicks on "Tide - Original Scent" that the user is then prompted to select the size."
SELECT amount FROM YOUR_TABLE WHERE productName = whatever_user_selected
"To add even more complexity to the task: I also have products in the same table named:
"Tide - Mountain Spring"."
The query above will also return that.
What you can do is :
$Query = 'SELECT productName, amount, unit FROM products';
$Data = array();
while($Assoc = mysql_fetch_assoc($Query)){
if(!isset($Data[$Assoc['productName']])){
$Data[$Assoc['productName']] = array();
}
$Size = $Assoc['amount'].' '$Assoc['unit'];
$Data[$Assoc['productName']][] = $Size;
}
// Now what you can do is :
foreach($Data as $ProductName => $Amount){
echo $ProductName.' has :<br />';
if(count($Amount) > 0){
foreach($Amount as $Key => $Value){
echo $Value.'<br />';
}
} else {
echo 'Nothing<br />';
}
}
This however doesn't solve the problem on MySQL's side. IT will work in PHP wihtout problem. It's not beautiful but it's working.
For the first problem, you could create two tables:
products - this is where you store all the information about a product except for the specifics such as different sizes, colors, etc.
attributes - you would link to the product and for each attribute you specify a value
products
id | description
---+------------
1 | crazy shirt
2 | clown shoe
attributes
product | name | value
--------+-------+-------
1 | color | green
1 | color | blue
1 | size | medium
2 | size | large
You can optimize the attributes table further by creating a attribute_names table (and even an attribute_values table).
For your second problem, you could either:
create a related product id column inside the products table; this would limit you to only one related product per product.
create a related product table in which you store combinations between two products.
related_products
product_id | related_product_id
-----------+-------------------
1 | 2
1 | 3
That would create a relationship between product 1 and products 2 and 3.
Hope this helps.
Create a foreign key to sublabels, and order them with a counter. This will look like.
Product Table:
Product ID (key)
Brand ID
Price
Brand Table:
Brand ID (key)
Brand
Sublable Table:
ID
Product ID
Order Index
Value
Size Table:
Size ID
Value
Unit
ProductSize Table:
Size ID
Product ID
Then, you'll divide into subcategories using subsequent sublabels.
Products
10 | 6 | 1.99
11 | 6 | 2.99
12 | 6 | 3.99
13 | 6 | 1.99
14 | 6 | 2.99
15 | 6 | 3.99
Brand
6 | Tide
Sublabel
30 | 10 | 1 | Original Scent
30 | 11 | 1 | Original Scent
30 | 12 | 1 | Original Scent
30 | 13 | 1 | Mountain Spring
30 | 14 | 1 | Mountain Spring
30 | 15 | 1 | Mountain Spring
Size Table
1 | 50 | fl.oz.
2 | 75 | fl.oz.
3 | 100 | fl.oz.
Product Size Table
1 | 10
1 | 13
2 | 11
2 | 14
3 | 12
3 | 15

Categories