简体   繁体   English

在MySQL中有效地连接3个表

[英]Joining 3 tables efficiently in MYSQL

I have 3 tables like this: 我有3张桌子,像这样:

images (~10,000 rows) 图片(约10,000行)

id | place_id | filename 
---|----------|----------
 1 |     4    |  abc.jpg
 2 |     3    |  def.jpg
 3 |     4    |  ghi.jpg
 4 |     7    |  jkl.jpg

tags (~100 rows) 标签(约100行)

id |   name   |
---|----------|
 1 |   tagA   |
 2 |   tagB   |
 3 |   tagC   |
 4 |   tagD   |

tagsToImages (~30,000 rows) tagsToImages(〜30,000行)

id |  tag_id  | image_id
---|----------|----------
 1 |     1    |    4
 2 |     3    |    2
 3 |     2    |    4
 4 |     1    |    1

As an example, the last table shows that the tag with id = 1 is linked with the image with id = 4. 例如,最后一个表格显示id = 1的标记与id = 4的图像链接。

I've got two questions, one pretty simple (I think!), and one more difficult. 我有两个问题,一个很简单(我认为!),另一个更困难。

Simple question 简单的问题

Given a place_id, how can I list all the tags that have image in that place_id? 给定一个place_id,我如何列出该place_id中具有图像的所有标签? An example would be: 一个例子是:

Given place_id = 7, return tagA, tagB. 给定place_id = 7,返回tagA,tagB。

Hard question 难以回答的问题

What I'd like to do is to select all the images with a certain place_id, and associate each image with a list of tags like so: 我想做的是选择所有带有特定place_id的图像,并将每个图像与标签列表相关联,如下所示:

Select all with place_id = 4, whilst joining to tags info. 选择所有place_id = 4,同时加入标签信息。

 filename |    tags    
-----------------------
  abc.jpg | tagA       
  ghi.jpg | tagA, tagB 

Would this be better to do in PHP by performing multiple queries, or can I do this using MYSQL? 通过执行多个查询在PHP中这样做会更好,还是可以使用MYSQL做到这一点?

  1. SELECT i.place_id, t.name as tag_name
    FROM images i
    INNER JOIN tagsToImages tti ON (tti.image_id = i.id)
    INNER JOIN tags t ON (t.id = tti.tag_id)
    WHERE i.place_id = 7

  2. SELECT i.filename, GROUP_CONCAT(t.name SEPARATOR ',') AS tags
    FROM images i
    INNER JOIN tagsToImages tti ON (tti.image_id = i.id)
    INNER JOIN tags t ON (t.id = tti.tag_id)
    WHERE i.place_id = 4 GROUP BY i.filename

It's always better to avoid multiple queries if possible. 如果可能的话,最好避免多个查询。
*Be aware that the maximum length of GROUP_CONCAT is controlled by group_concat_max_len variable. *请注意, GROUP_CONCAT的最大长度由group_concat_max_len变量控制。 If you are expecting to get a long list of concatenated strings, you might need to change the default value. 如果希望获得一长串连接的字符串,则可能需要更改默认值。

UPDATE UPDATE
If you want the queries to display images with no tags associated, change INNER JOIN s to LEFT JOIN s 如果希望查询显示没有标签的图像,请将INNER JOIN s更改为LEFT JOIN s

Simple Question 简单问题

SELECT name 
FROM images 
RIGHT JOIN tagsToImages on images.id = tagsToImages.image_id 
RIGHT JOIN tags ON tags.tag_id = tagsToImages.image_id 
WHERE place_id = '7'

For simple question, use join which will be more efficient: 对于简单的问题,请使用join ,它将更加高效:

select
    t.name as `Tag`
from
    images i
left join
    tagsToImages ti on ti.image_id = i.id
left join
    tags t on t.id = ti.tag_id
where
    place_id = $place_id

For hard question, see GROUP_CONCAT : http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat 如有疑问,请参见GROUP_CONCAThttp : //dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

使用join发出单个查询比添加循环,多个数据结构以及手动比较PHP中的值要好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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