简体   繁体   中英

Database design for select performance

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?

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.

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 

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM