SQL - Insert multiple categories to column - mysql

I have a table where I store products, and in the same table I store the ID of the category I want the product to be in.
My product table looks like this:
id | product_name | category_id | price
And then I have my category table:
id | category
My problem is to know how I can insert multiple categories into my category_id, and if it is possible.
If not, whats the best way that I could do it?

It is possible but you really don't want to go there. Storing multiple values in a single datarow column is a terrible idea in 99.99999% of the cases.
For more information, read Is storing a delimited list in a database column really that bad?, where you will see a lot of reasons why the answer to this question is Absolutely yes!
What you want to do is to add another table to store the relationship between the products and the categories. This is referred to as a many to many relationship.
This new table should hold the product id in one column and the category id in the other one, and have a composite primary key that is the combination of both these columns.
This way, you can have many products in the same category, and many categories for the same product.

You need a many to many relationship, which mean you need a third table let's call it ProductCategories, in this case you will have
Products
id | product_name | category_id | price
Category
id | category
ProductCategories
PruductID | CategoryID (combined PK)

Related

Table item many relationship

I know this is not code realated but wasnt sure where to post it. If this is the wrong spot please let me know where to post as opposed to just a down vote. Basically I am setting up my first DB on my own. I am a little conffused on how to set some tables up. I understand the basic relational model by using a unique ID to pair up tables but what about an item in a table that has many relations.
Examble:
User Table
ID | Name | Email
Product Table
ID | Name | Price | User_ID
Now I know I can pair the 2 using the User_ID in the product table but what if the product can belong to multiple users? How do I associate the the product by using the User_ID to multiple users?

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.

Foreign key to multiple records

I have two tables like so:
Table1
| itemid (PK)|
| typeid (FK)|
| item count |
Table2
| typeid (PK)|
| type name |
Table2 have 4-5 records in it. ...And I'm stuck at this point... Basically the item can be of all types (it can have typeid (FK) = NULL or all 4-5). I just can't get my head round this..At the moment when I add new item to Table1 (using phpmyAdmin ui) it gives me a choice of one FK as a dropdown list.. But what if the item is of two or three types..? It's probably a piece of cake but my brain has stalled... What would be the best way to do it?
Your design support 1-to-many relationship. Perhaps, you need many-to-many relationship between Table1 and Table2. If yes, you need to add a new link table:
Table3:
itemid(FK)
typeid(FK)
You can define a composite key on itemid and typeid in Table1.
That allows combinations of 1-1, 1-2, 3-1, 3-4, etc on itemid and typeid values.
Even your question is not much clear, but what I am understanding that you are not able to insert records in child table (table1) as record does not exist in master table (table 2).
So first you need to add required typeid in master table (table2) then you can enter in its child table.
If your requirement is something different then elaborate, so that you can get better help from community.

Database table design - are my fields correct?

I need to sell items on my fictitious website and as such have come up with a couple of tables and was wondering if anyone could let me know if this is plausible and if not where i might be able to change things?
I am thinking along the lines of;
Products table : ID, Name, Cost, mediaType(FK)
Media: Id, Name(book, cd, dvd etc)
What is confusing me is that a user might have / own many products, but how would you store an array of product id's in a single column?
Thanks
You could something like store a JSON array in a text or varchar field and let the application handle parsing it.
MySQL doesn't have a native array type, unlike say PostgreSQL, but in general I find if you're trying to store an array you're probably doing something wrong. Of course every rule has its exceptions.
What your probably want is a user table and then a table that correlates products to users. If a product is only going to relate to one user then you can add a user ID column to your Products table. If not, then you'll want another lookup table which handles the many to many relationship. It would look something like this:
------------------------
| user_id | product_id |
------------------------
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 2 |
| 3 | 1 |
| 3 | 5 |
------------------------
I think one way of storing all the products which user has in one column is to store it as a string where product ids are separated by some delimiters like comma. Though this is not the way you want to solve. The best way to solve this problem would be to have a seperate user table and than have a user product table where you associate userid with product id. You could than simple use a simple query to get list of all the products owned by a particular userid
As a starting point, try to think of the system in terms of the major parts - you would have a 'warehouse', so you need a table to list the products you have, and you are going to possibly have users who register their details with you for regular visits - so an account per user. You would generally hold all details of a single product in the same row of the same table (unless you have a really complex product to detail, but not likely). If you're going to keep track of products bought per user account, there's always the option of keeping the order history as a delimited list in a large text field. For example: date,id,id,id,id;date,id,id. Or you could simply refer to order numbers and have a separate table for orders placed [by any customer].
What is confusing me is that a user might have / own many products, but how would you store an array of product id's in a single column?
This is called a "many-to-many" relationship. In essence you would have a table for users, a table for products, and a table to map them like this:
[table] Users
- id
- name
[table] Products
- id
- name
- price
[table] Users_Products
- user_id
- product_id
Then when you want to know what products a user has, you could perform a query like:
SELECT product_id FROM Users_Products WHERE user_id=23;
Of course, user id 23 is fictituous for examples sake. The resulting recordset would contain the id's of all the products the user owns.
You wouldn't store an array of things into a single column. In fact you usually wouldn't store them in separate columns either.
You need to step away from design for a bit and go investigate third normal form. That should be you starting point and, in the vast majority of cases, your ending point for designing database schemas.
The correct way of handling variable size "arrays" is with two tables with a many to one relationship, something like:
Users
User ID (primary key)
Name
Other user info
Objects:
Object Id (primary key)
User id (foreign key, references Users(User id)
Other object info
That's the simplest form where one object is tied to a specific user, but a specific user may have any number of objects.
Where an object can be "owned" by multiple users (I say an object meaning (for example) the book "Death of a Salesman", but obviously each user has their own copy of an object), you use a joining table:
Users
User ID (primary key)
Name
Other user info
Objects:
Object Id (primary key)
User id (foreign key, references Users(User id))
Other object info
UserObjects:
User id (foreign key, references Users(User id))
Object id (foreign key, references Objects(Object id))
Count
primary key (User id, Object id)
Similarly, you can handle one or more by adding an object id to the Users table.
But, until you've nutted out the simplest form and understand 3NF, they won't generally matter to you.

Mysql table. Should I use multiple tables?

I'm implementing a price database where multiple sellers sell the same product at different prices. Each product is unique, and is identified by its model_number. Right now I have 1 seller in my price table. I am looking for the best way to build a table that can list multiple prices with each price being a field for a row whose primary key is model_number
The table looks like this:
model_number | seller | price
abc Store1 99.99
This structure works well when there is only 1 seller, as the primary key is model_number and my query to update the price uses on duplicate key update, which only updates the product if the price changes. Furthermore, the primary key is the model_number, but if I have multiple sellers that have the same model_number but with a different price, I believe when updating the table, the database will get confused as there will be duplicates of model_number.
Should I give each seller a unique key for their product? for instance, should seller_1 have a primary key of seller_1 and keep that value the same so the database knows to update if the price field of seller_1 changes.
Thanks
You can make the model_number and the seller primary key. That way you can have several tuples with the same model_number as long as the sellers differ.
model_number | seller | price
abc Store1 99.99
abc Store2 9.99
Is this what you want?
Three tables:
Seller, Seller_Product, Product
Each row of the linking table Seller_Product contains two Foreign Keys to corresponding Seller and Product row. The price is an attribute of the linking between a Seller and a Product. So it becomes a field in the linking table.
Seller: ID, Name, ...
Seller_Product: Seller_ID, Product_ID, price, availability, ...
Product: ID, Name, model_number, manufacturer, ...
This is a common table design for N:M Relationship.
So far your table structure looks good, all you would need to do is add the seller column as part of the primary key of the table. What you have here is a Many-to-Many relationship between products and sellers. That many to many relationship has some additional data, which is the price.
I think what you mean by "give each seller a unique key for their product" is actually what they call a surrogate key. You could give the table a primary key column so it looks like this
id | model_number | seller | price
Where id is the primary key of the table, and model_number and seller is are secondary keys and foreign keys, but that is really up to you, either way will work just fine.
Many to many relationships are what you are dealing with here.
You want three tables for this solution:
Products:
A table with products information, including a unique auto-incrementing id.
Sellers:
A table with sellers information, including a unique auto-incrementing id.
Products_To_Sellers:
A table with product_id, and seller_id ( INDEX these columns individually )
With this approach, you can JOIN the tables to view sellers products, but you ultimately have a SCHEMA that scales infinitely
[seller] [product_seller] [product]
-id seller.id -id -price
product.id
if you need products to be unique, you'll need another table:
[seller] [product_seller] [product] [seller_price]
-id seller.id -id product.id
product.id seller.id
-price