2011-12-12 43 views
1

使用FIND_IN_SETLIKE時,我很頭痛,得到正確的結果。如何正常化我當前的數據庫結構

例如我的數據庫值在這個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 

問題

如何規範&重組我的C urrent數據庫上面,並且容易我計算多少用戶喜歡黃色,棕色等。

回答

1

您需要額外的鏈接表。

tbl_colors 
---------- 
color_id 
color_name 

tbl_users 
--------- 
user_id 
... 

tbl_users_colors_link 
--------------------- 
user_id 
color_id 

請注意,鏈接表不應包含唯一字段。也不需要主鍵。只有索引id字段是有道理的。

+0

鏈接表應該有一個主鍵 - 一個innodb集羣。 –

+0

MRA沒有提到數據庫引擎,但我的答案也適用於InnoDB,因爲InnoDB會在內部自動創建一個6字節的unqiue密鑰。你不需要創建一個。 –

1

將USER放在他/她自己的表中,然後在USER_COLOUR中記錄他們的偏好,例如,

User ID Colour ID 
1   10 
1   11 
1   15 
2   10 
2   7 

請注意重複出現的用戶ID和顏色ID。這就是衆所周知的多對多的關係,因爲1個用戶可以喜歡很多顏色,而且每種顏色都可以被很多用戶喜歡。

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返回的行數。 多數民衆贊成那我該怎麼做。

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)