Store multiple data tables in single database table - mysql

Im designing MySql database for store multiple products such as computers,mobile phones,pen drives....etc.each product has different features such as
**Computers has**
Processor
Ram
HDD
Monitor Size
....etc
**Mobile phone has**
Display Size
Network type
OS
Internal Memory
....etc
**Pendrive has**
Capacity
USB Version
....etc
And i have to store unlimited number of products, instead of creating separate tables for each product how to create database structure to store these information on one or fixed number of tables(data tables + mapping tables).(i think Wordpress store data in this kind of format, it uses few tables and store any number field related to post/category within those tables).any help/idea to solve this problem would be appreciated.

Consider this
Create three table product, feature, product_feature and maybe product_photos
Product database will be
pid, p_name, p_description, p_price, ...
insert query
INSERT INTO (p_name, p_description, p_price, ....) VALUES(?,?,?,...)
feature table will
fid, f_name, f_description, ...
insert query
INSERT INTO (F_name, F_description, ....) VALUES(?,?,?,...)
now the product_feature table will be
id, pid, fid
query for one product
// say a product Id is 1
INSERT INTO (pid, fid) VALUES(1, 10)
INSERT INTO (pid, fid) VALUES(1, 15
INSERT INTO (pid, fid) VALUES(1, 30)
where pid and fid are foreign keys with relations, phpmyadmin can do that for you
you can then add a product with multiple features
then maybe the photo table
foto_id, photo_name, photo_path ....
use InnoDB for all the tables
Let me know if you need further help

You need to design a table in such a way that it covers all attributes for all products. This would help you insert any type of product in to that table. But, keep in mind that if there are 4 products with 10 different attributes, you end up creating 40 columns and might use only 10 to insert data at any point of time.

You can select one approach used by some ORM like hibernate or doctrine
https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/inheritance.html
http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html
Your selection depends on your data and how you will use it.
If you never will get a list with different kind of devices at once you should use different tables.
If you plan that all "devices" should share some fields like "ref", "name", "description", "price", "weight", etc, you should use one table because take a simple list with all kind of devices will be easy and low cost, but the table can grown if you plan to add more types of devices and properties.
If you plan that this fields will increase the table then you should split concrete properties of each type of device in different tables and use a discriminator field in the devices table that will allow you to make joins.
If the properties of the devices will grown a lot (or dynamically), then you should consider to use a table with fields: attribute and value. In this case the queries will be more heavy.
So basically you can do:
computer->
mobile->
pendribe->
or:
devices-> type, price, name, processor, ram, internal memory, capacity, usb version
or:
devices->type, price, name
computer-> processor, ram
mobile-> internal memory
pendribe-> usb version
or:
devices -> id, price, name
attributes-> id, id_attribute, value

Related

How to store many to many relationship with extra column data

in the above scenario 'signs and symptoms' is a multi selection and if 'others' selected 'specify-others' field must be filled . how to store this .
what is the best table structure for performance and querying
Either to provide 15 columns in single table and store null if no value or to store foreign key of symptoms in another table (in this strategy how to store 'others symptom' description column ie specify-other field data).
There is no universal answer, your choice may depend on multiple factors including external issues, i.e. coding framework you use to support database (if any). The "classic" way to do it:
1. Patient table:
id (PK)
name
2. Symptom table:
id (PK)
symptom
3. Patient to Symptom table:
id (PK)
patient_id (FK)
symptom_id (FK)
other_symptoms (text)
But once again, any approach (including this one) has its own pros and cons and this is not a universal solution.
I would definitely exclude the 15 columns in a table option because whenever a new symptom would be needed to be added, and it will be needed rather sooner than later, you'll have to:
alter the table schema
the code that displays the symptoms
the code that inserts/updates patient records
who knows what else.
I'd go with a classic many to many relationship, with tables similar to:
patients: patient_id, name, etc
symptoms: symptom_id, name, description, etc
patient_symptoms: patient_id, symptom_id
Even better would be an extra table:
visits: doctor_id, patient_id, date, other_symptoms
And then, your patient_symptoms table can be related to an actual visit to a doctor:
patient_symptoms: visit_id, symptom_id

How to aggregate different kinds of products in SQL?

Let's say I want to sell computers and monitors.
Let's say I want the computer to store parameters like Memory (GB), Processor Speed (GHz), hard drive type, hard drive size.
And monitors have parameters like Size (inches), resolution and ratio.
All products have name, price and availability.
What's the best way to store them in MySQL database if later I want to filter it eg. "All products in price range >500$"?
Use an attribute-value table:
CREATE TABLE attributes (
product_id INT, -- foreign key to products table
attribute_name VARCHAR(32), -- size, resolution, ratio, etc.
attribute_value VARCHAR(32) -- value of the attribute
);
Then you can do a query like:
SELECT product_id
FROM attributes
WHERE attribute_name = 'size' AND attribute_value = 32
and you can join this table with the products table to get things like the price.
If you want to combine multiple attributes, see
mySQL - Create a New Table Using Data and Columns from Three Tables

Store a unique reference to a Mysql Table

I am creating a site that is sort of ecommerce-ish. I want to give my users a perfect search ability using specific attributes that differ from product to product. I plan to create 1 products table storing the basic information that is shared among products i.e Name, Description, Price and a few others. Then I plan to create several "details" table say categories_computers with columns Processor, HDD, RAM, etc and another table say table_shoes with columns MATERIAL, SIZE, GENDER, etc.
I am new to Mysql but not to the concept of Databases. I don't think I will have a problem storing this data to each table. My issue comes about from reads. It won't be hard to query a product id but I think it would be extremely wasteful to query all details tables to get the details of the product since 1 product can only have 1 details.
So my question is how can I store a reference to a table in a column so that a product has say ID, Name, Description, Price, Details_Table_ID or something similar to save on queries. Do tables have unique ids in Mysql? Or how does the Stackoverflow community suggest I go about this? Thanks.
EDIT
Silly me, I have just remembered that every table name is uniques so I can just use that, so my question changes to how I can write a query that contains one cell in a table A to be used as a reference to a Table name.
Don't use separate details tables for each category, use a generic details table that can store any attribute. Its columns would be:
Product_ID INT (FK to Products)
Attribute VARCHAR
Value VARCHAR
The unique key of this table would be (Product_ID, Attribute).
So if Product_ID = 1 is a computer, you would have rows like:
1 Processor Xeon
1 RAM 4GB
1 HDD 1TB
And if Product_ID = 2 is shoes:
2 Material Leather
2 Size 6
2 Gender F
If you're worried about the space used for all those attribute strings, you can add a level of indirection to reduce it. Create another table Attributes that contains all the attribute names. Then use AttributeID in the Details table. This will slow down some queries because you'll need to do an additional join, but could save lots of space
Think about just having a single ProductDetails table like this:
ProductDetailID (PK)
ProductID (foreign key to your Products table)
DetailType
DetailValue
this way you do not have to create new columns every time you add a new product detail type. and you'll have many ProductDetail rows for each productid, which is fine and will query ok. Just be sure to put an index on ProductDetails.ProductID !
Since this is an application so you must be generating the queries. So lets generate it in 2 steps. I assume you can add a column product_type_id in your Product table that will tell you which child table to user. Next create another table Product_type which contains columns product_type_id and query. This query can be used as the base query for creating the final query e.g.
Product_type_id | Query
1 | SELECT COMPUTERS.* FROM COMPUTERS JOIN PRODUCT ON COMPUTERS.PRODUCT_ID = PRODUCT.PRODUCT_ID
2 | SELECT SHOES.* FROM SHOES JOIN PRODUCT ON COMPUTERS.PRODUCT_ID = PRODUCT.PRODUCT_ID
Based on the product_id entered by the user lookup this table to build the base query. Next append your where clause to the query returned.

OneToMany relationships taking more database space

We re-factored our user specific configuration from
create table user (id, name, ..., config1, config2, config3, ..) to
create table user (id, name, ...);
create table user_config (id, user_id, config_val);
Our MySQL database size increased by a factor of 2 after making this change and migrating the users from the older table to the newer table. We made this so that user configuration can be made extensible, but why does the space requirement go up because of this. What could be the reason.
If you had an oritinal table with 20 fields, and 1,000,000 users, that would be 20 * 1,000,000 = 20,000,000 items of data.
Say, for example, you now have the same number of users, but decrease the table to 10 fields, and had 10 config rows with three fields each (as per your code). This would be 10 * 1,000,000 + 10 * 3 * 1,000,000 = 50,000,000. This would be a factor of 2.5.
So, basically, for each configuration variable, you are now adding an id (Primary Key), and a user (Foreign Key) field. Added to that, there is now more indexing data that has to be generated.
SO, it could very well be the case that your data requirements have dramatically increased.

SQL: flavours of INSERT INTO

(MySQL) I am trying to migrate a "subscription" table into 3 new tables: "product", "subscription", "actual" where "actual" is the name of the actual product, say, newsletter. The subscription has a FK reference to product and the actual has FK reference into subscription.
I know the INSERT INTO SELECT statement can copy data probably from many table to one; is there a statement to do the opposite, one to many tables for my case?
I'm not aware of an SQL statement that will do what you want. Just do several INSERT INTO SELECTs one after the other. It may be faster to do them one at a time anyway.
I think you can use three seperate insert into select statements. First you convert the product table, then the subscription where you can use an embedded select to find the id in the product table:
insert into subscription (some_column, FK_id,...)
select something, (select id from product where <your where clause>),...
and finally convert the actual table using an embedded select to get the id from the subscription table.