Как разработать таблицу MySQL для облака тегов?
-
25-09-2019 - |
Вопрос
У меня есть статьи на своем сайте, и я хотел бы добавить теги, которые будут описаны каждую статью, но у меня проблемы с дизайном MySQL таблицы для тегов. У меня есть две идеи:
- Каждая статья будет иметь полевые «теги», а теги будут в формате: «Tag1, Tag2, Tag3»
- Создайте другую таблицу под названием Tags с полями: Tag_Name, Article_ID
Поэтому, когда я хочу теги для статьи с ID 1, я бы бег
SELECT ... FROM tags WHERE `article_id`=1;
Но я также хотел бы знать 3 самых подобных статей, сравнивая теги, поэтому, если у меня есть статья, которая имеет теги «PHP, Mysql, Erlang» и 5 статей с тегами: «PHP, MySQL», «Erlang, Ruby», «PHP Erlang», «MySQL, Erlang, JavaScript», я бы выбрал 1., 3. и 4., поскольку эти 3 имеют самые те же теги с основной статьей.
Также другой вопрос, какой лучший способ получить 10 "самых используемых тегов"?
Решение
Как правило, для такого рода во многих отношениях есть три таблицы:
- "
article
" стол- Первичный ключ = ID
- "
tag
" стол- Первичный ключ = ID
- Содержит данные каждого тега:
- Название, например
- A "
tags_articles
«Таблица, которая действует как таблица присоединения и содержит только:id_article
: внешний ключ, который указывает на статьюid_tag
: внешний ключ, который указывает на тег
Таким образом, нет дублирования данных любого тега: для каждого тега есть один, и только одна линия в tag
стол.
И для каждой статьи вы можете иметь несколько тегов (т.е. несколько строк в tags_articles
стол) ; И, конечно же, для каждого тегов вы можете иметь несколько статей.
Получение списка тегов для статьи, с этой идеей является вопросом дополнительного запроса, например:
select tag.*
from tag
inner join tags_articles on tag.id = tags_articles.id_tag
where tags_articles.id_article = 123
Получение трех «самых похожей» статей означало бы:
- Выберите статьи, которые имеют теги, которые имеют первую статью
- Используйте только те, которые имеют самое важное количество идентичных тегов
Не проверено, но идея может быть то, что бы выглядела так:
select article.id, count(*) as nb_identical_tags
from article
inner join tags_articles on tags_articles.id_article = article.id
inner join tag on tag.id = tags_articles.id_tag
where tag.name in ('php', 'mysql', 'erlang')
and article.id <> 123
group by article.id
order by count(*) desc
limit 3
В основном вы:
- Выберите идентификаторы статей для каждого тега, который присутствует на вашей первоначальной статье
- Как есть внутреннее соединение, если статья в БД имеет 2 теги, которые соответствуют
where
пункт безgroup by
пункт, для этой статьи будут две строки - Конечно, вы не хотите переоформивать статью, которую вы уже имели - что означает, что она должна быть исключена.
- Как есть внутреннее соединение, если статья в БД имеет 2 теги, которые соответствуют
- Но, как вы используете
group by article.id
, будет только одна строка на статью- Но вы сможете использовать
count
, чтобы узнать, сколько тегов в каждой статье общего с начальным
- Но вы сможете использовать
- Затем это только вопрос сортировки на количество меток и получает только третью три строки.
Другие советы
Во-первых, вы захотите использовать предложение Pascal Martin о дизайне таблицы.
Что касается поиска подобных статей, вот что-то, чтобы начать вас. Учитывая, что @article_id - это статья, которую вы хотите найти совпадения, и @ Tag1, @ Tag2, @ Tag3 - это теги для этой статьи:
SELECT article_id, count(*)
FROM tags_articles
WHERE article_id <> @article_id
AND tag_id IN (@tag1, @tag2, @tag3)
GROUP BY article_id
ORDER BY count(*) DESC
LIMIT 3
Да, но вы не ответили на мой главный вопрос, как получить 3 самых похожих статей?
Ответ: Просто ищите одинаковые идентификаторы тегов в объединенной таблице (Tags_Articles). Соберите их и создайте шаблон.
Например: Статья 1 имеет теги: 1,2 Статья 2 имеет теги: 2,3,4 Статья 5 имеет теги: 6,7,2 Статья 7 имеет теги: 7,1,2,3
Если вы хотите 3 самых похожих статей для статьи 1, вы должны искать теги 1,2. Вы найдете статью 7, наиболее похожи и 2 и 5 имеют некоторые сходства.