Edit product selling location using mysql - mysql

I'm building a e-Commerce platform (PHP + MySQL) and I want to add a attribute (feature) to products, the ability to specify (enable/disable) the selling status for specific city.
Here are simplified tables:
cities
id name
==========
1 Roma
2 Berlin
3 Paris
4 London
products
id name cities
==================
1 TV 1,2,4
2 Phone 1,3,4
3 Book 1,2,3,4
4 Guitar 3
In this simple example is easy to query (using FIND_IN_SET or LIKE) to check the availability of product for specific city.
This is OK for 4 city in this example or even 100 cities but will be practical for a large number of cities and for very large number of products?
For better "performance" or better database design should I add another table to table to JOIN in query (productid, cityid, status) ?
availability
id productid cityid status
=============================
1 1 1 1
2 1 2 1
3 1 4 1
4 2 1 1
5 2 3 1
6 2 4 1
7 3 1 1
8 3 2 1
9 3 3 1
10 3 4 1
11 4 3 1

For better "performance" or better database design should I add
another table
YES definitely you should create another table to hold that information likewise you posted rather storing in , separated list which is against Normalization concept. Also, there is no way you can gain better performance when you try to JOIN and find out the details pf products available in which cities.
At any point in time if you want to get back a comma separated list like 1,2,4 of values then you can do a GROUP BY productid and use GROUP_CONCAT(cityid) to get the same.

Related

Maintaining relationship and history in mysql databases

I am designing a mysql database and have come across these relations which will grow in the future.
Suppose Customer is tied to 2 different tables Policies and Options.
Each customer has multiple relationship with policies and likewise with options. Since I am keeping a details and history of the table as well every time I add a relation with customer, I will have to maintain another 2 tables. To calculate the price the customer owes, I will have to go thru customer_policies then customer_options and calculate the total price. Also the number of tables increases as the relationship increases.
If customer has a relation with policies it will have 2 tables -
customer_policies and customer_policies_details.
If customer has one more relation with options, it will add 3 more -
customer_options, and customer_option_history.
Like wise, it will keep on adding 2 more tables if there is one more
relation and the problem grows and grows.
I have tried 2 different options which I have mentioned below. I wanted to know what is the best way to solve this problem so that the table can be maintained as the relation grows.
Option 1:
customer_policies:
CustomerPolicyId CustomerId PolicyId Status
1 1 1 Active
2 1 2 Active
customer_policies_details:
CustomerPolicyDetailsId CustomerPolicyId Price
1 1 10
2 2 20
customer_options:
CustomerOptionId CustomerId OptionId Status
1 1 1 Active
2 1 2 Active
customer_options_details:
CustomerOptionDetailsId CustomerOptionId Price
1 1 10
2 2 20
Option 2:
Create a single table customer_selections and use Type and Id field instead like so:
customer_selections:
CustomerSelctionId CustomerId Type Id Status
1 1 Policy 1 Active
2 1 Policy 2 Active
3 1 Option 1 Active
4 1 Option 2 Active
customer_selection_details:
DetailsId CustomerSelctionId Price
1 1 10
2 2 20
3 3 10
4 4 20
To create a history of this I just have to create a customer_selections_details and keep track of all changes.
There should be better ways to solve this problem.

How can i convert a comma separated columns into junction table?

I am pretty new to mysql and this site. I got an old mysql database (100.000 entries) to migrate to our new system. This is the old table:
CUSTOMER
Customer_ID Name Categories
1 Bob 1,2
2 Phil NULL
3 Ines 10,8
4 Carol 1
5 Rick 13,2
And i need the following structure:
CUSTOMER
Customer_ID Name
1 Bob
2 Phil
3 Ines
4 Carol
5 Rick
Category
Category_ID Category_Name
1 Biker
2 Doctors
3 Teacher
... ...
13 Drivers
CustomerHasCategory
Customer_ID Category_ID
1 1
1 2
3 10
3 8
4 1
5 13
5 2
Thanks for any help.
I also had this problem but not in MySQL. I solved it with Python using the Pandas library. So, the exact steps I followed won't be useful for you. However, I'll show you the general idea behind the solution I used.
Below is image of the original column
First, I splitted the text into columns using the comas as the delimiter.
Next, I 'stacked' the columns
Finally, I removed the artefact column(s). So, I have only the ID and the values columns. This creates a one-to-many relationship.

query the same field multiple times in the same query

I need to filter a table in mysql but can't get past the beginning.
The table has 2 fields:
ID_house house_feature
1 1
1 2
1 4
1 5
2 1
2 3
2 4
3 1
3 2
3 3
I need to filter this table using the following parameters:
house feature = 1
AND
house feature = 2
AND
house feature = 3
So that I get all houses with the requested feature.
I already tried to create something similar to this:
SELECT *
FROM houses
WHERE
house_feature = 1
AND
house_feature = 2
AND
house_feature = 3
But it doesn't work as I expected.
Is there a way to get this result with MySQL?
It seems that I acn filter the table using only the OR operator but this way I can't get the right result.
Thanks in advance for any help.
tony
You can do so ,by matching the distinct count of features per house ,so the house with exactly these 3 features will be returned
SELECT *
FROM t
WHERE
house_feature IN(1 ,2,3)
group by ID_house
having count(distinct house_feature) = 3
Demo

mySQL - foreign key to multiple tables? [duplicate]

This question already has answers here:
Possible to do a MySQL foreign key to one of two possible tables?
(6 answers)
Closed 8 years ago.
I am fumbling my way through phpMyAdmin and mySQL. I’m creating something where a customer can register multiple products. The data coming in is:
Category > Type > Size > Color
So for example:
Cookware > Oven > 5 qt > Blue
Bakeware > Casserole > 3qt > Blue
Accessories > Textiles > N/A > Blue
Etc.
I have set up one table with categories, and 4 tables to cover each product type.
Categories
ID Category
1 Cookware
2 Bakeware
3 Accessories
4 Serveware
Cookware Table
ID Type
1 Oven
2 Skillet
3 Roaster
Bakeware Table
ID Type
1 Casserole
2 Pie Dish
3 Baker
Etc.
Then, in the registration table, I set up a foreign key to link the category to the category table. So it would look something like this:
ID CustID Category Type Size Color
1 20 2 1 11 34
1 20 1 1 9 34
(sorry the formatting is so terrible! not sure how to fix)
But, I’m stuck on how to link the product type to the correct product type table since it is dependent on which category they picked. Hopefully this makes sense. Maybe I don't even need to link them and can still request the data somehow through a query?
Merge the last 2 tables ?
ID Type Category
1 Oven 1
2 Skillet 1
3 Roaster 1
4 Casserole 2
5 Pie Dish 2
6 Baker 2

Storing data in a link table

Supoose I have the following:
tbl_options
===========
id name
1 experience
2 languages
3 hourly_rate
tbl_option_attributes
=====================
id option_id name value
1 1 beginner 1
2 1 advanced 2
3 2 english 1
4 2 french 2
5 2 spanish 3
6 3 £10 p/h 10
7 3 £20 p/h 20
tbl_user_options
================
user_id option_id value
1 1 2
1 2 1
1 2 2
1 2 3
1 3 20
In the above example tbl_user_options stores option data for the user. We can store multiple entries for some options.
Now I wish to extend this, i.e. for "languages" I want the user to be able to specify their proficiency in a language (basic/intermediate/advanced). There will also be other fields that will have extended attributes.
So my question is, can these extended attributes be stored in the same table (tbl_user_options) or do I need to create more tables? Obviously if I put in a field "language_proficiency" it won't apply to the other fields. But this way I only have one user options table to manage. What do you think?
EDIT: This is what I propose
tbl_user_options
================
user_id option_id value lang_prof
1 1 2 null
1 2 1 2
1 2 2 3
1 2 3 3
1 3 20 null
My gut instinct would be to split the User/Language/Proficiency relationship out into its own tables. Even if you kept it in the same table with your other options, you'd need to write special code to handle the language case, so you might as well use a new table structure.
Unless your data model is in constant flux, I would rather have tbl_languages and tabl_user_languages tables to store those types of data:
tbl_languages
================
lang_id name
1 English
2 French
3 Spanish
tbl_user_languages
================
user_id lang_id proficiency hourly_rate
1 1 1 20
1 2 2 10
2 2 1 15
2 2 3 20
3 3 2 10
Designing a system that is "too generic" is a Turing tarpit trap for a relational SQL database. A document-based database is better suited to arbitrary key-value stores.
Excepting certain optimisations, your database model should match your domain model as closely as possible to minimise the object-relational impedance mismatch.
This design lets you display a sensible table of user language proficiencies and hourly rates with only two inner joins:
SELECT
ul.user_id,
u.name,
l.name,
ul.proficiency,
ul.hourly_rate
FROM tbl_user_languages ul
INNER JOIN tbl_languages l
ON l.lang_id = ul.lang_id
INNER JOIN tbl_users u
ON u.user_id = ul.user_id
ORDER BY
l.name, u.hour
Optionally you can split out a list of language proficiencies into a tbl_profiencies table, where 1 == Beginner, 2 == Advanced, 3 == Expert and join it onto tbl_user_languages.
i'm thinking it's a mistake to put "languages" as an option. while reading your text it seems to me that english is an option, and it might have an attribute from option_attributes.