#php #mysql #search
#php #mysql #Поиск
Вопрос:
Многие типы систем используют теги для организации контента, включая блоги и StackOverflow. Допустим, я создаю веб-сайт фильмов и хочу, чтобы пользователи могли помечать фильмы, а также искать фильмы, используя комбинации тегов.
Вот пример структуры базы данных:
movies:
id, name
movie_tag_options (used to provide users with list of available tag options):
id, name
movie_tags:
id, m_id, mto_id
Допустим, есть фильм под названием «Трансформеры 9 — Взрывы», и у него есть теги «действие», «PG-13» и «ужасный фильм». Я хочу, чтобы пользователи могли найти этот фильм, выполнив поиск по запросу «действие, страница 13, ужасный фильм».
Я взорву строку тегов в PHP, чтобы получить массив тегов:
action
PG-13
terrible movie
Итак, мой вопрос в том, как мне использовать имена тегов для поиска фильмов с этими тегами? Фильмы могут иметь и другие теги, но должны быть возвращены только в том случае, если у них есть все теги в поиске.
Единственное решение, которое я могу придумать, — это денормализовать имя тега и сохранить его в movie_tags
as well as movie_tag_options
(т. Е. Добавить дублирующийся name
столбец movie_tags
), а затем создать запрос на PHP, который генерирует JOIN
операторы для каждого тега. Что-то вроде этого:
SELECT id, name FROM movies
JOIN movie_tags mt0 ON mt0.name = "action"
JOIN movie_tags mt1 ON mt1.name = "PG-13"
JOIN movie_tags mt2 ON mt2.name = "terrible movie"
JOIN
Строки будут сгенерированы с помощью PHP и вставлены в запрос.
Недостатком этого подхода является хранение имен тегов в двух таблицах вместо одной.
Есть ли лучший способ?
Ответ №1:
или вы можете использовать
select a.name, count(c.id) c
from movies a
join movie_tags b on a.id = b.m_id
join movie_tag_options c on b.mto_id = c.id
where c.name in ('action', 'PG-13', 'terrible movie')
group by a.id
having c = 3;