MySQL: нормализация и объединение таблиц для функции тегов - PullRequest
0 голосов
/ 21 марта 2012

Моя текущая структура базы данных:

     `images`            `tags`             `images_tags`
 ________________    ______________    ________________________
| id | title     |  | id | name    |  | id | image_id | tag_id |
|----|-----------|  |----|---------|  |----|----------|--------|
|  1 | Ivysaur   |  |  1 | fire    |  |  1 |     2    |    1   | Charizard: fire
|  2 | Charizard |  |  2 | flying  |  |  2 |     2    |    2   | Charizard: flying
|  3 | Squirtle  |  |  3 | water   |  |  3 |     1    |    4   |   Ivysaur: grass
|  4 | Pidgey    |  |  4 | grass   |  |  4 |     4    |    2   |    Pidgey: flying
 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯    ¯¯¯¯¯¯¯¯¯¯¯¯¯¯    ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Я хочу вывести теги с соответствующими значениями (имя).

if ($_GET["pokemon"] == "2") {
    // output Charizard's tags: fire, flying
}

Но я пытаюсь найти правильный запрос для этого. INNER JOIN мне незнаком, и объяснение того, как это работает, было бы очень полезно.

Ответы [ 3 ]

1 голос
/ 21 марта 2012

Хороший дизайн схемы, ваш запрос будет выглядеть так:

SELECT t.* 
FROM tags AS t
INNER JOIN image_tags AS it ON it.tag_id = t.id
WHERE it.image_id = 2;

Внутреннее соединение просто означает, что любая строка в таблице тегов ДОЛЖНА иметь соответствующую строку в таблице image_tags.

1 голос
/ 21 марта 2012

Для текущей структуры таблицы:

SELECT
    tags.name
FROM tags
    LEFT JOIN image_tags ON tags.id = images_tags.tag_id
    LEFT JOIN images ON images_tags.image_id = images.id
WHERE images.id = 2

Но я бы посоветовал вам внести некоторые изменения в структуру.

  1. избавиться от image_tags.id.Это бессмысленно.Вы можете создать составной первичный ключ из комбинации тегов_id и image_id.

  2. остановить анонимный столбец id.Это бесполезная привычка, которую люди выбирают из плохих учебников и из худших библиотек ORM.Идентификатор таблицы tags должен иметь одинаковое имя в таблицах tags и image_tags.Это сделает вашу структуру БД более легкой для отслеживания, и у нее будет еще один perk * ​​1019 * для запроса:

    SELECT
        tags.name
    FROM tags
        LEFT JOIN image_tags USING(tag_id)
        LEFT JOIN images USING(image_id)
    WHERE images.image_id = 2
    

Упрощает чтение. DonВы думаете ...

Чтобы понять, как работают JOIN операторы, эта статья может помочь.Также я бы порекомендовал прочитать SQL Antipatterns .

1 голос
/ 21 марта 2012

Pokemon.ЛОЛ!xD

Для вывода тегов:

SELECT t.id, t.name
FROM tags AS t 
   INNER JOIN images_tags AS r ON r.tag_id =t.id
   INNER JOIN images AS i ON r.image_id =i.id
WHERE i.id ='2'
  1. Выберите из таблицы тегов и введите псевдоним «t»
  2. Присоединитесь к третьей таблице (ассоциации) спсевдоним "r" и с r.tag_id = t.id
  3. Соедините таблицу изображений с псевдонимом "i" и с r.image_id = i.id
  4. Наконец, установите фильтр: i.id = '2' (но будет mysql_real_escape_string($_GET['pokemon']), поскольку вы не хотите внедрять SQL)

Теперь ярлык:

if(isset($_GET['pokemon')) {
    $image_id = (int) $_GET['pokemon'];
    $r = mysql_query("SELECT t.* FROM tags t, tags_images r WHERE r.tag_id =t.id AND r.image_id ='$image_id'");
    while($tag = mysql_fetch_assoc($r)) {
        echo $tag['name'] . '<br />';
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...