Mysql - normalization of database - mysql

I have a MySQL database and I want to normalize it in an efficient way. I have a table in my database in which i am getting data into column in the form of array. Actually I have three tables (details, country, material). In table "country" I have two column that are (id,country_name). In table "material" I have two column (id, material) and in table "details" i have four column (id, vendor, countries, materials). In this scenario, each vendor has multiple countries and materials and I am inserting ids of country and material in details table. Here is the screenshot:
so how I accurately normalize my database? Thanks in advance

Remove countries and materials columns from Details table.
You can create a fourth table which will depict the relationship between vendor,country and material:
vendor_id country_id material_id
1 3 5
1 6 9
1 7 24
Here all the columns will be foreign key and together they will form composite primary key

you need to design two new tables detail_country and detail_material also you need to modify your detail table as fellow
detail : id , vendor
detail_country : detail_id , country_id
detail_material : detail_id , material_id

Related

Can Child table from 1-many be a parent to another table thats many to 1

1)GroupParent1 table( Gid, value) (111,Shirt)
2)GroupChild1(Gcid, Gid, value) (1,111, blue)(2,111, cotton) i.e. Stores attributes for products so a group of attributes in this table can have one or more row.
ISSUE: Another table called 3)Price should store price for " only" groups that exist in table 2 above using redesign/ PK-FK or both.
Like Blue, cotton shirt can have a price Or Red, Silk shirt can have another price.
In short, how can we enforce pk-fk constraint or redesign them so that Price can only be created if & only if both the other tables have data.
I can put Pk From table 1 to either of tables & can enforce referential constraint.
But I am unable to use table 2 to enforce table 3 have entry only if the group has been created in table 2.
As table 2 has group so I am unable to do that as a group has multiple rows i.e. 2 in this case.
You have 2 ways to do it:
First (if one element of GroupChild1 table can only has one element),
you can add one column to 'GroupChild1' to keep the price.
Second (if one element of GroupChild1 table can has one or more prices),
you should create a table called 'Prices' with a relation with 'GroupChild1'.
[Price] -- {id, price, groupchild1_id}
I hope it will help you.

MYSQL auto fill column values from another table

im very new to databases :) now with that said.
I have a table (sellers) with the columns: Seller_id, Seller_logo. There are 5 sellers.
I have a table (details) with the columns : Details_id, Seller_logo, Product, Price. There are 1000 Products.
Today i decided to insert a new column at the (sellers) table, with name "seller_name" and i fill in the values very easy since there are just 5 sellers.
The problem : How can i add in the (Details) table, a new column "seller_name" and automatic fill the values of the from the (sellers) table?
*i created a relation between Seller_logo on the tables (Sellers and Details)
Thanks in advance.
The relationship should be by Seller_id and I suppose the details table is for products? I would recommend this structure and then when you query the details table you would ideally use MySQL Join Syntax http://dev.mysql.com/doc/refman/5.0/en/join.html to get the related seller_name
**Sellers**
1. Seller_id
2. Seller_name
3. Seller_logo
**Details**
1. Details_id
2. Seller_id (foreign key)
3. Product
4. Price

Prevent duplicate entries in a database table based on 2 columns

I record the datas of a competition in an MySQL database.
I need to have unique entry for each player so i’ve done this :
alter table xtu_datas_competition add unique index(email);
It works perfectly.
But there are several competitions, so i have also a colum id_ competition and i want to have unique entry for email and for specific colum id_ competition
For example :
2 identical email for 2 identical colum id_ competition : duplicate
2 identical email for 2 different colum id_ competition : not duplicate
How can i adapt my previous code ?
You simply have to define a unique constraint containing both columns:
alter table xtu_datas_competition add unique index(id_competition,email);
Hope this will help you.

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.

Multiple foreign key for 'extra data' table

i have a logical question for optimization tables relation in MySQL (and even other DBMS).
there are many table with different columns and structures in my database. for a specific reason, i need to create a new table, names "extra_data" with there columns (id, table, content). each table (even "extra_data" itself) MAY needs to store extra data for undefined columns. so this extra data that is a PHP array or object, first serialized and then transform to Base64 code and inserted to "eaxtra_data" table content column. id and table name of target table row, stored in id and table columns in "extra_data" too.
for example if there is two tables names "users" and "posts" and each of them need to store extra data in "extra_data" table:
"users" table:
id name gender ...
1 Tom Male ...
2 Mary Female ...
3 Jack Male ...
...
 
"posts" table:
id title date ...
1 news 4/11/2014 ...
2 article 4/51/2014 ...
...
 
"extra_data" table:
id table content
1 users #$!^...
2 users #$!^...
2 posts #$!^...
...
id and table is primary key in "extra_data" table. so problem is when target row (form example row 2 in users) has been changed or removed, related row in "extra_data" must updated automatically if it's necessary. but the way to set foreign key in many table and in two columns (id, table) together, is imprecise to me! thanx for any help
DarkMaze,
I see where you come from with this "extra_data" table. I don't agree, though. Once it goes against the principles of database normalization and this logic is not clear on a design perspective. I'd rather serialize whatever data you want to add to extra_data content column and save it into its respective table.
Back on the question, the only solution I see so far is to add triggers on every table related to "extra_data" in order to add/remove/update records. Which is not very productive.
Cheers,
http://en.wikipedia.org/wiki/Database_normalization