Эффективное объединение 3 таблиц в MYSQL

У меня есть 3 таблицы:

изображения (~ 10 000 строк)

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

теги (~ 100 строк)

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

tagsToImages (~ 30 000 строк)

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

Например, последняя таблица показывает, что тег с id = 1 связан с изображением с id = 4.

У меня два вопроса, один довольно простой (я думаю!), И еще один сложный вопрос.

Простой вопрос

Учитывая place_id, как я могу перечислить все теги, у которых есть образ в этом place_id? Примером может служить:

Учитывая place_id = 7, верните tagA, tagB.

Сложный вопрос

То, что я хотел бы сделать, – это выбрать все изображения с определенным place_id и связать каждое изображение со списком таких тэгов:

Выделите все с помощью place_id = 4, присоединившись к тегам.

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

Было бы лучше сделать это на 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

Всегда лучше избегать нескольких запросов, если это возможно.
* Помните, что максимальная длина GROUP_CONCAT контролируется переменной group_concat_max_len . Если вы ожидаете получить длинный список конкатенированных строк, вам может потребоваться изменить значение по умолчанию.

ОБНОВИТЬ
Если вы хотите, чтобы запросы отображали изображения без привязанных тегов, измените INNER JOIN s на LEFT JOIN s

Простой вопрос

 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' 

Для простого вопроса используйте 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 

Для жесткого вопроса см. GROUP_CONCAT : http://dev.mysql.com/doc/refman/5.0/ru/group-by-functions.html#function_group-concat

выдача единого запроса с объединением лучше, чем добавление циклов, нескольких структур данных и ручное сравнение значений в PHP.