使用FIND_IN_SET
或LIKE
时,我很头疼才能获得正确的结果。
示例我的数据库中的值,如1,2,3,4,5,6,7,8
。
假设我有一个包含许多复选框的表单。每个复选框都带有动态值,可以由用户添加。示例值为颜色并具有green, yellow, white, black, red, pink, brown, etc...
我目前的结构tbl_colors
& tbl_users
color_id color_name
----------------------
1 yellow
2 black
3 green
. ...
. ...
20 pink
tbl_users
user_id color_id
----------------------
1 1,2,3,4
2 3,4,5,6,8,9,10
3 1
. ...
. ...
20 1,10,20
问题
我如何规范化&重构我上面的当前数据库,让我轻松计算用户喜欢黄色,棕色等等。
答案 0 :(得分:1)
你需要一个额外的链接表。
tbl_colors
----------
color_id
color_name
tbl_users
---------
user_id
...
tbl_users_colors_link
---------------------
user_id
color_id
请注意,链接表不应包含唯一字段。也不需要主键。只有索引id字段才有意义。
答案 1 :(得分:1)
将USER放入他/她自己的表中,然后在USER_COLOUR中记录他们的偏好,例如
User ID Colour ID
1 10
1 11
1 15
2 10
2 7
请注意重复出现的用户ID和颜色ID。这被称为多对多关系,因为1个用户可以喜欢多种颜色,并且许多用户都可以喜欢每种颜色。
答案 2 :(得分:1)
table colors
id
color_id
color_name
table users
id
table user_color( or whatever )
id
user_id
color_id
这样,每个用户选择的颜色都有一个单独的表和一个条目,而不是每个color_id行有多个数字。 然后,您可以根据查询中的color_id计算返回的行数。 多数民众赞成我将如何做到这一点。
答案 3 :(得分:1)
tbl_user_color
id, user_id, color_id
--------------------
1 1 1
2 1 2
3 1 3
4 1 4
5 3 1
6 20 1
7 20 10
8 20 20
...
答案 4 :(得分:1)
请看以下链接:
http://www.xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/
http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html
然后按照(省略参照完整性)的方式设计您的模式:
drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varchar(32) unique not null
)
engine=innodb;
drop table if exists colours;
create table colours
(
colour_id smallint unsigned not null auto_increment primary key,
name varchar(255) unique not null,
user_counter int unsigned not null default 0
)
engine=innodb;
drop table if exists user_colours;
create table user_colours
(
user_id int unsigned not null,
colour_id smallint unsigned not null,
primary key (user_id, colour_id) -- note the clustered composite primary key
)
engine=innodb;
delimiter #
create trigger user_colours_after_ins_trig after insert on user_colours
for each row
begin
update colours set user_counter = user_counter + 1 where colour_id = new.colour_id;
end#
delimiter ;
insert into users (username) values ('alpha'),('beta'),('delta'),('gamma');
insert into colours (name) values ('red'),('green'),('blue');
insert into user_colours (user_id, colour_id) values
(1,1),(1,3),
(2,1),(2,2),(2,3),
(4,3);
select * from users;
+---------+----------+
| user_id | username |
+---------+----------+
| 1 | alpha |
| 2 | beta |
| 3 | delta |
| 4 | gamma |
+---------+----------+
4 rows in set (0.00 sec)
select * from colours;
+-----------+-------+--------------+
| colour_id | name | user_counter |
+-----------+-------+--------------+
| 1 | red | 2 |
| 2 | green | 1 |
| 3 | blue | 3 |
+-----------+-------+--------------+
3 rows in set (0.00 sec)
select * from user_colours;
+---------+-----------+
| user_id | colour_id |
+---------+-----------+
| 1 | 1 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 4 | 3 |
+---------+-----------+
6 rows in set (0.00 sec)