Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I have a platform with multiple clients and each has a large set of demographics that I need to store. With this in mind, it seems I could do one of two things in MySQL. Either:
Option #1: Have a large table with everyone's demographics. For example:
Table: clientDemographics
id | clientID | firstName ....
1 | 34 | John ......
2 | 12 | Fred ......
Option #2: Split out each client to having their own table:
Table: client34_demographics
id | firstName ....
1 | John ......
Table: client12_demographics
id | firstName ....
1 | Fred ......
Are there any advantages to splitting the tables out by client (efficiency, security, scalability) or disadvantages? Which of these would be a better method? Thanks!
Your second example is not a good idea (creating a table for each demographic). Instead, I would go with something more "normalized" that contains unique identifiable information in the client table, and then additional meta data (demographics) as a lookup:
Table: Clients
ClientId | FirstName | LastName | Email
-------------------------------------------------
1 | John | Smith | jsmith#email.com
Table: Demographics
DemographicId | Name
-------------------------------------------------
1 | Gender
2 | Nationality
3 | Age
Table: Clients_Demographics
CDId | ClientId | DemographicId | Value
-------------------------------------------------
1 | 1 | 1 | Male
2 | 1 | 2 | American
3 | 1 | 3 | 27
In this way you can easily sort on demographic types, demographic values, clients, etc and all the while saving space in your database, increasing query performance, and keeping your data scalable. By scalable I mean, need to add another Demographic? Just add another row to the Demographics table and then associate a value in the Clients_Demographics table with a Client. If they value is not set (i.e. no row exists) then you know that value can be seen as empty in your forms until they actually set a value.
Related
Suppose I have a experts table like this :
+-----------+----------+----------+--------+
| expert_id | name | family | active |
+-----------+----------+----------+--------+
| 1 | ali | ahadi | 1 |
| 2 | reza | hosseini | 1 |
| 3 | hossein | rezaei | 0 |
| 4 | mohammad | gholami | 1 |
+-----------+----------+----------+--------+
And in the other hand there is a questions table like this :
+-------------+-------+-----------+
| question_id | title | expert_id |
+-------------+-------+-----------+
| 1 | A | 1 |
| 2 | B | 2 |
| 3 | C | 4 |
| 4 | D | 1 |
| 5 | E | 2 |
| 6 | F | 4 |
+-------------+-------+-----------+
I'm working on a Question-Answer App. when a user asks a new Question I want to select an expert(of course activated expert, means an expert that has active field equal to 1) that can answer to question .(expert_id field holds the selected Expert ID in the questions table).
But I do not want this to be a random selection. Instead, I want to be sequentially as you can see in the expert_id of questions table.
In fact ,since that daily many questions may be asked I would like divide questions between the experts equally.
I want to do it in laravel But I do not know how I could implement this logic.
Can anyone help me to do that or suggest better ways?
I would suggest you keep a running total of the number of questions each expert has, that way you can assign it to the person with the lowest number of questions. You could even make this the total number of unanswered questions each expert has, which gets lowered when an expert answers the question so those experts that answer questions more frequently get more questions and those with less time to answer questions, or difficult questions that take a long time to answer, get less questions.
The way to do this would be to add another field onto the experts table, num_questions. When selecting experts you could do something like $expert = Expert::where('active', '=', 1)->orderBy('num_questions')->first(); then just assign the question to that user and increment the num_questions field by one for that user. You'd then just need to decrement that number when the user answers a question (if you want unanswered questions over total questions).
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Based on my situation, should I combine all symptoms into one row as my method 1 below or method 2 that create more rows. The reason I don't like method 1 is that I have to use - to separate each symptom, and later I need to use php explode('-') to separate them and use LIKE to match them.
Method 2 will create more rows, and I think I will create more table to separate them.
Method 1:
disease symptoms
HIV pain-cough-hair loss
Flu cought-running nose-fever
cacer lose weight-fever-fatigue
Method 2:
disease symptoms
HIV pain
HIV cough
HIV hair loss
... ...
... ...
Out of your two methods, method 2 would be preferred. As #JNevill notes, storing multiple pieces of data in one column becomes a nightmare when searching or filtering data.
My full recommendation would be to use option 3 however. Take a look at the below design:
Table 1: DISEASES
+------+-----------+
| id | name |
+------+-----------+
| 1 | HIV |
|------|-----------|
| 2 | FLU |
|------|-----------|
| 3 | Cancer |
+------+-----------+
Primary Key:
id
Table 2: SYMPTOMS
+------+-----------+
| id | name |
+------+-----------+
| 1 | pain |
|------|-----------|
| 2 | cough |
|------|-----------|
| 3 | hair-loss |
+------+-----------+
Primary Key:
id
Table 3: DISEASES-SYMPTOMS
+-------------+--------------+
| disease_id | symptom_id |
+--------------+--------------+
| 1 | 1 |
|--------------|--------------|
| 1 | 2 |
|--------------|--------------|
| 1 | 3 |
+--------------+--------------+
Primary Key:
(disease_id, symptom_id)
Foreign Keys:
DISEASES.id -> DISEASES_SYMTPOMS.disease_id
SYMTPOMS.id -> DISEASES_SYMTPOMS.symptom_id
Establish your base tables DISEASES and SYMPTOMS. Then establish a 3rd table representing a JOIN of the first two tables. This normalization of the data will simply the structure of your application and prevent duplication of data since each disease can have multiple symptoms and each symptom can belong to multiple disease.
SAMPLE QUERY (MySQL):
SELECT
d.id,
d.name,
s.name
FROM DISEASES as d
INNER JOIN DISEASES_SYMPTOMS AS ds ON d.id = ds.disease_id
INNER JOIN SYMPTOMS AS s ON ds.symptom_id = s.id;
SAMPLE QUERY RESULT:
+------+----------------+----------------+
| id | disease_name | symptom_name |
+------+----------------+----------------+
| 1 | HIV | pain |
|------|----------------|----------------|
| 1 | HIV | cough |
|------|----------------|----------------|
| 1 | HIV | hair-loss |
+------+----------------+----------------+
It depends how normalized you want your database to be. The more normalized approach would be to create a symptoms table that houses all symptoms, a disease table that houses all diseases, and another table with links diseases to symptoms probably by disease_id and symptom_id. And the less normalized approach is like your method 1 where you include all the symptoms as a field in the table separated by some delimiter or put into an array if you are using a database that supports arrays.
Create two master tables for disease & symptoms. And then create a third table say .disease_symptom include the two foreign key column say disease_id & symptom_id and refer to the corresponding master table
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am new to PHP and MySQL and require help with an issue I am facing. I am trying to create a table that is cleaner then the following:
Table example
Item |Part |Quantity
Item1 |123 |2
Item1 |124 |2
Item2 |123 |1
Item2 |125 |3
I can do this with a normal table but I can envision the database having tons of repeat rows with duplicate data. For example I used Item1 multiple times to identify each part.
I was wondering if there was a cleaner way to store this data in my database? I will be using PHP to store the data into MySQL. I am also looking to make the Item column unique but as it stands, can not do this.
I looked into serialize, join as well as an array but I couldn't figure out how to make it all fit so I thought I would ask here. The end results would be a PHP report that says:
Item 1 uses the following parts
Part 123 : Quantity 2
Part 124 : Quantity 2
Item 2 uses the following parts
Part 123: Quantity 1
Part 125: Quantity 3
Any help would be greatly appreciated.
You have a many-to-many relation between your items and your parts.
So you need 3 tables (item, part, and link_item_part).
Your item table will have an id as a primary key. Same goes for your part table. Your link_item_part table will have a compound primary key build from two foreign keys one on item, the other one on part.
-- item table
| id | name |
+----+--------+
| 1 | Item 1 |
| 2 | Item 2 |
-- part table
| id | name |
+----+------+
| 1 | 123 |
| 2 | 124 |
| 3 | 125 |
-- link_item_part
| item_id | part_id | quantity |
+---------+---------+----------+
| 1 | 1 | 2 |
| 1 | 2 | 2 |
| 2 | 1 | 1 |
| 2 | 3 | 3 |
Edit: don't store data in a format that is not native to the database if you want to manipulate them with queries. If you store data in a non-native format, you'll have a hard time to manipulate it, and it will be slow.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have three tables and I would like to select from the tables without producing duplicates.
The table are as follows:
Customers
id | name | lastName
---------------------------------------
1 | john | doe
2 | helen | keller
Orders
The userID column is a foreign key that references John Doe, so John orders 3 items.
id | userID | order
---------------------------------------
1 | 1 | pizza
2 | 1 | pasta
3 | 1 | lasagna
CustomerRating
The userID column is a foreign key that references John Doe, so John leaves 5 reviews.
id | userID | rating | comment
-------------------------------------------------
1 | 1 | 5/5 | was good
2 | 1 | 5/5 | excellent
3 | 1 | 4/5 | great
4 | 1 | 4/5 | great
5 | 1 | 4/5 | great
How would I select from the 3 tables where I can get a return results that look like this?
id | name | lastName | order | rating
-----------------------------------------------------------------
1 | john | doe | pasta | 5/5
| | | pizza | 5/5
| | | lasagna | 4/5
| | | | 4/5
| | | | 4/5
I've tried joining these tables, but since John has left 5 reviews and only ordered 3 times, the id, name,lastName, and order columns gets filled with duplicate data.
Thanks!
I don't have any experience in MySQL but I assume that it works similar to MSSQL.
So the format in which you are expecting the output is not possible. You can rather get the order and rating column values as comma separated
Here is a similar kind of question that might help you
including example based on link
try something like this
SELECT Customers.id, Customers.name, Customers.lastName,
GROUP_CONCAT(Orders.order) OrderedDishes,
GROUP_CONCAT(CustomerRating.rating) RatingsGiven
FROM
..... rest of your query .....
There are ways to discard duplicates (SELECT DISTINCT, UNION, GROUP BY) but it is not clear whether users update existing rating or create new ones. And what you want to see: the last rating or the average one
On the other note - i would change your entire setup:
order table would contain order_id, customer_idand other order related stuff like order_date
products table that would describe each of your dishes and their info like price, description etc
order_products table with fields order_id and prduct_id
if users rate products then your rating table would need at least product_id, customer_id, rate_value. I'd also add ratingDate That way you can get averages or select the last one by Max(ratingDate)
I think you need to add an orderID field to the CustomerRating table else there is no way to relate an item to its rating.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I have a MySQL that lists about 500 items. Users can register at the site and mark which item they have already. This is a simple php that reads the table and each row.
How should I structure the database so that each user can have a particular setting for each item?
So that when Bob opens his account, he sees he already has ITEM 1, but when Mary opens it, she'll have ITEM 1 as missing and she can see who has that ITEM 1 twice or more times so that she may contact whoever has more than 1 of an item?
You could do something like this:
Have a table that shows which users have what items...
Table Name: user_items
primary_key | user_id | item_number
-----------------------------------
1 | 1 | 1
2 | 1 | 1
3 | 1 | 2
4 | 2 | 2
or you could have something like this
primary_key | username | item_number
-----------------------------------
1 | bob | 1
2 | bob | 1
3 | bob | 2
4 | mary | 2
This table above shows that:
User 1 / Bob has:
item 1 x2
item 2
User 2 / Mary has:
item 2
You can create other table with three columns, foreign key for item, foreign key for user and amount of that item.
You will keep there information that Bob has ITEM 1.