Reputation: 1
For performance, waht is the best database user table design for hobbies and city field when i want to filter a user with a specific hobby in specific city?
SOLUTION 1 - N1 TABLE
USER TABLE
ID........| NAME..| CITY.....| HOBBIES.............................|
VALUE| VALUE | VALUE | VALUE1, VALUE2, VALUE3 |
SOLUTION 2 - N1 TABLE
USER TABLE
ID........| NAME..| CITY.....| HOBBIY1 | HOBBIY2 | HOBBIY3 | HOBBIY4 | HOBBIY5 | HOBBIY6 |
VALUE| VALUE | VALUE | VALUE ...| VALUE ....| VALUE ....| VALUE ....| VALUE ...| VALUE ...|
SOLUTION 3 - N2 TABLE
1 - USER TABLE
ID ....... | NAME..| CITY.... |
VALUE | VALUE | VALUE |
2 - HOBBIES TABLE
ID ....... | HOBBY |
VALUE | VALUE |
And what is the best php query to list the user of a city with an hobby?
Upvotes: 0
Views: 120
Reputation: 28227
How about:
Tables:
---------
user:
user_id, (Primary Key - DB will create index automatically)
username, (Add unique index to prevent duplicate usernames)
created_on
city:
city_id, (Primary Key)
country, (You may want to index some of these location fields, but I would
region, wait until you see the need for them based on your queries)
city,
latitude,
longitude
user_location:
user_id, (If you want a user to only have one location, then create a primary
city_id, key for user_id and city_id. (Composite) If you want to allow multiple
update_on per user then create a non-unique composite index on user_id and city_id
user_hobby:
user_id, (Create a unique composite index on user_id and hobby_id)
hobby_id
hobby:
hobby_id, (Primary Key)
hobby_name (Create a unique index to prevent duplicate hobbies with different keys)
SQL:
---------
SELECT user_id, username, c.country, c.region, c.city
FROM user u
JOIN user_location ul ON (u.user_id = ul.user_id)
JOIN city c ON (ul.city_id = c.city_id)
JOIN user_hobby uh ON (h.user_id = uh.user_id)
JOIN hobby h ON (uh.hobby_id = h.hobby_id)
WHERE h.hobby_name = 'Model Cars';
You may find that some of these aren't necessary for your application, or that you need to add additional indexes, but this should be a good place to start. You didn't specify what db you were using, but I'm going to assuming your using a LAMP stack. Here is info for creating indexes via MySQL. An example of a unique index on username in your user table would be:
CREATE UNIQUE INDEX idx_unq_user_username ON user(username);
It may seem like a lot of tables for a trival example, but in a relational database you typically want to normalize your tables as much as possible. When you have queries that are common, then you can create views that make the data accessible with simpler queries. Another aspect of setting up your tables this way is that it allows you to easily add columns where they make sense. In your initial schema, if you stored city within the user table and then wanted to add lat/long, it begins to make your users table look more and more like a location table with user info haphazardly placed within it.
Normalizing does nice things at the database level as well like allowing changes of data to propagate with very few actual updates, helping with the density of data to reduce I/O requirements to satisfy a query, and data integrity.
Upvotes: 2
Reputation: 9329
1 - USER TABLE (ID, Name, City)
2 - HOBBIES TABLE (ID, Name)
3 - USERSTOHOBBIES TABLE (UserID [foreign key], HobbyID [foreign key])
And you'll need to create the appropriate indexes.
Upvotes: 0
Reputation: 1007
Solution 2
That'll lift the DB to third normal form (higher is better) where solutions 1 is second normal form.
And something with inner joins, most likely this:
Select * from usertable inner join hobbiestable on usertable.id = hobbiestable.id
Upvotes: 0