选择性能的数据库设计


Database design for select performance

就性能而言,当我想过滤特定城市中有特定爱好的用户时,什么是爱好和城市字段的最佳数据库用户表设计?

解决方案1-N1表

用户表

ID…..| NAME..|城市……|爱好|
VALUE|VALUE|VALUE|1,VALUE2,VALUE3|


解决方案2-N1表

用户表

ID…..| NAME..|城市……|哈比1|哈比2|哈比3|哈比4|哈比5|哈比6|
VALUE|VALUE|VALUE|值…|值……|值……|值……|值…|值…|


解决方案3-N2表

1-用户表

ID……..|名称..|城市|
值|值|值|


2-兴趣爱好表

ID……..|业余爱好|
VALUE|VALUE|


列出有兴趣的城市用户的最佳php查询是什么?

怎么样:

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';

您可能会发现其中一些对于您的应用程序来说是不必要的,或者您需要添加额外的索引,但这应该是一个很好的起点。您没有指定使用的数据库,但我假设您使用的是LAMP堆栈。以下是通过MySQL创建索引的信息。用户表中用户名的唯一索引示例如下:

CREATE UNIQUE INDEX idx_unq_user_username ON user(username);

对于一个简单的例子来说,它可能看起来像是很多表,但在关系数据库中,您通常希望尽可能规范化表。如果有常见的查询,则可以创建视图,使数据可以通过更简单的查询访问。以这种方式设置表的另一个方面是,它允许您轻松地在有意义的地方添加列。在最初的模式中,如果您将城市存储在用户表中,然后想要添加lat/long,它会使您的用户表看起来越来越像一个位置表,其中随意放置了用户信息。

规范化在数据库级别做得很好,比如允许数据的更改只需很少的实际更新就可以传播,有助于提高数据密度以降低满足查询的I/O需求,以及数据完整性。

解决方案2

这将把DB提升到第三范式(越高越好),其中解决方案1是第二范式

还有一些内部连接,很可能是这样的:

Select * from usertable inner join hobbiestable on usertable.id = hobbiestable.id 

1-用户表(ID、名称、城市)


2-HOBBIES表格(ID,名称)


3-USERSTOHOBBIES表(UserID[外键],HobbyID[外键)

您还需要创建适当的索引。