MySQL не нравится запрос не работает


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

  • сообщения
  • теги

Таблица тегов структурирована следующим образом:

  • post_id
  • tag

Поэтому для каждого тега, заданного для сообщения, я создаю запись в таблице тегов. Если сообщение имеет 10 тегов, в таблице тегов будет 10 записей с этим post_id.

Сейчас я пытаюсь построить страницу поиска, на которой пользователи могут выполнять поиск сообщений, теги которых не содержат заданных ключевых слов. Однако это создает проблему. Один запрос типа:

SELECT DISTINCT posts.id, posts.title, posts.content
   FROM jobs, tags
   WHERE tags.tag NOT LIKE '%$keywords%' AND posts.id=tags.post_id

Не работает, потому что если сообщение имеет 6 тегов и один из них имеет ключевое слово, оно все равно будет возвращено, потому что другие 5 записей в таблице тегов не имеют этого ключевого слова.

Как лучше всего решить эту проблему? Каким-либо другим способом, кроме создания нового столбца в таблице posts, в котором хранятся все теги, разделенные запятыми, используемые только для поиска??

1 2

1 ответ:

Убедитесь, что у вас есть индексы, или это будет работать очень плохо:

SELECT posts.id, posts.title, posts.content
FROM posts 
WHERE NOT EXISTS (
  SELECT post_id from tags
  WHERE tags.tag LIKE '%$keywords%' 
    AND posts.id=tags.post_id
)

Здесь выводится список всех сообщений, исключая те, которые имеют тег, соответствующий указанному вами тегу. (Ваш исходный запрос ссылается на таблицу "задания". Я предположил, что это была опечатка для "сообщений".)

Табличные псевдонимы делают это немного чище:

SELECT p.id, p.title, p.content
FROM posts p
WHERE NOT EXISTS (
  SELECT t.post_id from tags t
  WHERE t.tag LIKE '%$keywords%' 
    AND p.id=t.post_id
)

Затем я бы создал эти индексы:

Posts: id, tag_id
Tags: post_id, tag

Затем выполните запрос с помощью' explain', чтобы проверить, хорошо ли он работает. Обновите свой вопрос с результатами и кто-то предложит дальнейшие советы. Настройка индекса - это больше проб и ошибок, чем что-либо еще, поэтому тестирование действительно необходимо.