How to display multiple values in a MySQL database? - sql

I was wondering how can you display multiple values in a database for example, lets say you have a user who will fill out a form that asks them to type in what types of foods they like for example cookies, candy, apples, bread and so on.
How can I store it in the MySQL database under the same field called food?
How will the field food structure look like?

You may want to read the excellent Wikipedia article on database normalization.
You don't want to store multiple values in a single field. You want to do something like this:
form_responses
id
[whatever other fields your form has]
foods_liked
form_response_id
food_name
Where form_responses is the table containing things that are singular (like a person's name or address, or something where there aren't multiple values). foods_liked.form_response_id is a reference to the form_responses table, so the foods liked by the person who has response number six will have a value of six for the form_response_id field in foods_liked. You'll have one row in that table for each food liked by the person.
Edit: Others have suggested a three-table structure, which is certainly better if you are limiting your users to selecting foods from a predefined list. The three-table structure may be better in the case that you are allowing them the ability to enter their own foods, though if you go that route you'll want to be careful to normalize your input (trim whitespace, fix capitalization, etc.) so you don't end up with duplicate entries in that table.

normally, we do NOT work out like this. try to use a relation table.
Table 1: tbl_food
ID primary key, auto increment
FNAME varchar
Table 2: tbl_user
ID primary key, auto increment
USER varchar
Table 3: tbl_userfood
RID auto increment
USERID int
FOODID int
Use similar format to store your data, instead a chunk of data fitted into a field.
Querying in these tables are easier than parsing the chunk of data too.

Use normalization.
More specifically, create a table called users. Create another called foods. Then link the two tables together with a many-to-many table called users_to_foods referencing each others foreign keys.

One way to do it would be to serialize the food data in your programming language, and then store it in the food field. This would then allow you to query the database, get the serialized food data, and convert it back into a native data structure (probably an array in this case) in your programming language.
The problem with this approach is that you will be storing a lot of the same data over and over, e.g. if a lot of people like cookies, the string "cookies" will be stored over and over. Another problem is searching for everyone who likes one particular food. To do that, you would have to select the food data for each record, unserialize it, and see if the selected food is contained within. This is a very inefficient.
Instead you'll want to create 3 tables: a users table, a foods table, and a join table. The users and foods tables will contain one record for each user and food respectively. The join table will have two fields: user_id and food_id. For every food a user chooses as a favorite, it adds a record to the join table of the user's ID and the food ID.
As an example, to pull all the users who like a particular food with id FOOD_ID, your query would be:
SELECT users.id, users.name
FROM users, join_table
WHERE join_table.food_id = FOOD_ID
AND join_table.user_id = users.id;

Related

Create an Access Query to see if in another field?

I am creating queries for my database, and I want to know if the Artist_Name Field Value (A string) is part of a field in a different table, Band. I want to see if the Artist_Name is in the Band_Members field. Both are short text fields. I am using the Design View to create this query, which I will later edit in SQL. I will attach an Image to show my Query Relationships and Fields: Query Relationships
You can use DCount function to count the number of records in Band having Band_Members equal to Artist_Name.
You can create a left join from Artist table to Band table, on fields Artist_Name and Band_Members, but note that it may blow up the number of records in your output if artists are part of multiple bands.
I don't understand the field Band.Band_Members though; I suppose there is some one-to-may relationship between a band and it's members.

Storing list of strings in MySql column

I have a users table which contains data for registered users, each row represents a user. One column in particular should contain a list of groups the user is part of, at the moment that column is of TEXT type and I'm storing that list as a string where groups are separated with a semicolon, something like:
admin;moderators;devteam
And I was wondering: "Is this a good idea?", is there a better/safer way to do this that doesn't require a lot of effort to implement or is this "ok"?
Here is a pic of the table as of now:
And I was wondering: "Is this a good idea?"
Short answer: probably not.
Why
If you will ever need to do any manipulation on that column, you will find yourself in big trouble. Simply selecting all users in a group will require some operations on a string (usually not performance-friendly). Same will hold true for sorting, joining and all the other operations SQL is great for.
Solution
What you describe is a typical example of N:N relationship, where each user can belong to multiple groups and each group can have multiple users in it.
The 'standard' way of modeling this relationship is creating a new table, where each row will represent a user belonging to a group. The columns will be group and userID.
With data from your example
userID | group
--------|----------
1 | admin
1 | moderator
1 | test
This allows to have one row for each user in the users table, and getting the groups of a specific user is as simple as
select group
from user_groups
where userID = '1'

How to deal with one single cell containg multiple values?

I'm having an exercise requiring to create two table for a travel business:
Activity
Booking
it turns out that the column activities in the Booking table references from the Activities table. However it contains multiple value. How do I sort it out? If I insert multiple rows there will possibly duplication in the Booking's primary key.
As Gordon mentioned you should refactor your tables for better normalization. If I interpret your intent correctly this is more like what your schema should look like. Booking should only contain an ID for adventure and an ID for Customer. You will add a row to [AdventureActivity] for each activity booked on a [Booking]. With this design you can JOIN tables and get all the data you require without having to try to parse out multiple values in a column.

Basic question: how to properly redesign this schema

I am hopping on a project that sits on top of a Sql Server 2008 DB with what seems like an inefficient schema to me. However, I'm not an expert at anything SQL, so I am seeking for guidance.
In general, the schema has tables like this:
ID | A | B
ID is a unique identifier
A contains text, such as animal names. There's very little variety; maybe 3-4 different values in thousands of rows. This could vary with time, but still a small set.
B is one of two options, but stored as text. The set is finite.
My questions are as follows:
Should I create another table for names contained in A, with an ID and a value, and set the ID as the primary key? Or should I just put an index on that column in my table? Right now, to get a list of A's, it does "select distinct(a) from table" which seems inefficient to me.
The table has a multitude of columns for properties of A. It could be like: Color, Age, Weight, etc. I would think that this is better suited in a separate table with: ID, AnimalID, Property, Value. Each property is unique to the animal, so I'm not sure how this schema could enforce this (the current schema implies this as it's a column, so you can only have one value for each property).
Right now the DB is easily readable by a human, but its size is growing fast and I feel like the design is inefficient. There currently is not index at all anywhere. As I said I'm not a pro, but will read more on the subject. The goal is to have a fast system. Thanks for your advice!
This sounds like a database that might represent a veterinary clinic.
If the table you describe represents the various patients (animals) that come to the clinic, then having properties specific to them are probably best on the primary table. But, as you say column "A" contains a species name, it might be worthwhile to link that to a secondary table to save on the redundancy of storing those names:
For example:
Patients
--------
ID Name SpeciesID Color DOB Weight
1 Spot 1 Black/White 2008-01-01 20
Species
-------
ID Species
1 Cocker Spaniel
If your main table should be instead grouped by customer or owner, then you may want to add an Animals table and link it:
Customers
---------
ID Name
1 John Q. Sample
Animals
-------
ID CustomerID SpeciesID Name Color DOB Weight
1 1 1 Spot Black/White 2008-01-01 20
...
As for your original column B, consider converting it to a boolean (BIT) if you only need to store two states. Barring that, consider CHAR to store a fixed number of characters.
Like most things, it depends.
By having the animal names directly in the table, it makes your reporting queries more efficient by removing the need for many joins.
Going with something like 3rd normal form (having an ID/Name table for the animals) makes you database smaller, but requires more joins for reporting.
Either way, make sure to add some indexes.

Join performance

My situation is:
Table member
id
firstname
lastname
company
address data ( 5 fields )
contact data ( 2 fields )
etc
Table member_profile
member_id
html ( something like <h2>firstname lastname</h2><h3>Company</h3><span>date_registration</span> )
date_activity
chat_status
Table news
id
member_id (fk to member_id in member_profile)
title
...
The idea is that the full profile of the member, when viewed is fetched from the member database, in for instance a news overview, the smaller table which holds the basis display info for a member is joined.
However, i have found the need for more often use for the member info that is not stored in the member_profile table, e.g. firstname, lastname and gender, are nescesary when someone has posted a news item (firstname has posted news titled title.
What would be better to do? Move the fields from the member_profile table to the member table, or move the member fields to the member_profile table and perhaps remove them from the member table? Keep in mind that the member_profile table is joined a lot, and also updated on each login, status update etc.
You have two tables named member so i have the feeling your question isn't formed correctly.
What is the relationship between these tables? It looks like you have 3 tables, all one-to-one. So all you need to do is change (fk to member_id in member_profile) to (fk to id in member).
Now you can join in data from either of the 2 extra tables as you wish, without always having to go through member_profile.
[Edit] Also I assume that member_profile.member_id is a fk to member.id. If not, I believe it should :)
Combine them into one table so you're normalizing the name data then create 2 views which replicate the original two tables would be the easy option
Separating the tables between mostly-static fields and frequently-updated fields will improve write performance. So I would stay with what you're doing. If you cache the information from both tables together in a member object, read performance (and thus joining) is less of an issue.