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.
Related
So I want to make a webapp that needs to store the following.
"Users"
some "Events"
and some "Customers"
each "Event" has a "User" which is represented by a userId column.
But each "Event" can have multiple customers, to be able to store all this info,
I thought it's better to have a new table "Customers_In_Events" that has 3 columns:
id, -- Not sure if that's needed
e_id -- Event ID
c_id -- Customer ID
I have 2 questions...
Is there some better way to do this?
If I decide to go with the way I mentioned (an extra table), Would the "id" column be needed?
I am using MySQL by the way.
You can use a bridge model to represent your data, which is also normalized.
every event can have multiple customers
every customer can have multiple events
so the tabkes would look like
Events events_coustmers cutonuers
e_id(PK) e_id(fk) c_id(Pk)
e_name c_id(fk) c_name
PK(e_id,c_id)
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
I have a situation where I am trying to get a value stored in one table, but have to go through several other tables on the same database to get the correct result.
Table 1 has a PK ID I can query, this PK will give me a new FK in table 2, this will give me a key to table 3 and table 3 will give me key to table 4 that has the value stored against the PK in table 1. If this made sense? I can not do something with the tables or the database, so I need to find a way to select the value in table 4 from the primary key I got in table 1.
Any ideas?
Edit 1 :
I will try to explain better. I have a filepath located in table 4. To get the correct filepath I need to first find the a project id in table 1. That same project id is a FK in table 2. In table 2 I need to find another id (let's call it "customer id") using project id as FK, the customer id is a FK in table 3. In table 3 I need to find purchase id using customer id as FK, the purchase id is a FK in table 4. With the correct FK (purchase id) in table 4, I am able to get the correct filepath. The filepath that coresponds with the project id from table 1.
I am using ASP.NET (Entity Framework) and a SQL database. I was thinking to use Linq, but is somewhat confused about how to do it. Join several tables or try to get the filepath that way?
Did this make it more clear?
use Linq join Query,..
One example, See here
Entity Framework Join 3 Tables
or search LINQ join in Google,you can find the solution yourself.
There are four regions with more than one million records total. Should I create a table with a region column or a table for each region and combine them to get the top ranks?
If I combine all four regions, none of my columns will be unique so I will need to also add an id column for my primary key. Otherwise, name, accountId & characterId would be candidate keys or should I just add an id column anyways.
Table:
----------------------------------------------------------------
| name | accountId | iconId | level | characterId | updateDate |
----------------------------------------------------------------
Edit:
Should I look into partitioning the table by region_id?
Because all records are related to a particular region, a single database table in 3NF(e.g All-Regions) containing a regionId along with other attributes should work.
The correct answer, as usually with database design, is "It depends".
First of all, (IMHO) a good primary key should belong to the database, not to the users :)
So, if accountId and characterId are user-editable or prominently displayed to the user, they should not be used for the primary key of the table(s) anyway. And using name (or any other user-generated string) for a key is just asking for trouble.
As for the regions, try to divine how the records will be used.
Whether most of the queries will use only a single region, or most of them will use data across regions?
Is there a possibility that the schemas for different regions might diverge?
Will there be different usage scenarios for similar data? (e.g. different phone number patterns for different regions)
Bottom line, both approaches will work, let your data tell you which approach will be more manageable.
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.