mysql和标记应用程序结构 - “不在”子选择语句中的替代方法

时间:2012-08-02 00:02:07

标签: mysql tags

在考虑我正在开发的Web应用程序的最佳mysql数据库结构时,需要使用标签进行项目分类,我决定选择,这似乎是最常见的方法:使用tag_map数据库表在项目表和标签表之间,例如我分别有一个Clients表和一个Tag Table:

Example of Clients table:
id,name
0,jack
1,john
2,anna

Example of Tags table:
id,tag
0,likes_oranges
1,likes_cars
2,likes_vacations

Example of tag_map
id,client_id,tag_id
0,0,0 (jack likes oranges)
1,0,1 (jack likes cars)
2,0,2 (jack likes vacations)
3,1,0 (john likes oranges)
4,1,1 (john likes cars)
5,2,1 (anna likes cars)

鉴于此分布,并假设我们客户端表可以增长超过一百万行,我的问题是: 查询有“假期”标签的所有客户的最佳方法是什么?

我的第一选择是使用:

select name from clients where id not in (select client_id from tag_map where tags.tag = 'likes vacations')

但是当client和tag_map表增长到数千条记录以上时,这个查询非常慢。

我还尝试将tag_map连接到客户端表,但由于所有客户端都分配了多个标记,因此使用 NOT NULL 也不起作用,因为我只想计算那些没有特定标签ID的人(喜欢度假)。

请就此类要求的最佳选择声明提供建议。

提前致谢!

ķ

1 个答案:

答案 0 :(得分:0)

确保在tag_map表中的client_id和tag_id上添加索引。如果没有索引,那么对于大量行,您的查询会非常慢。

使用explain select ...查看查询优化器如何优化查询。