Как создать таблицу MySql для облака тегов?

У меня есть статьи на моем сайте, и я хотел бы добавить теги, которые описывали бы каждую статью, но у меня возникли проблемы с таблицей mysql для тегов. У меня есть две идеи:--2-->

  1. каждая статья будет иметь поле "теги", а теги будут в формате:"tag1,tag2, tag3"
  2. создайте другую таблицу, называемую тегами, с полями: 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 "наиболее часто используемых тегов"?

3 ответов


как правило, для такого рода отношений "многие ко многим" существует три таблицы :

  • в "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 пункт, было бы две строки для этой статьи
    • конечно, вы не хотите повторно выбирать статью, которая у вас уже была , что означает, что она должна быть исключенный.
  • но, как вы используете group by article.id, будет только одна строка на статью
    • но вы сможете использовать count, чтобы узнать, сколько тегов каждая статья имеет общее с начальной
  • тогда речь идет только о сортировке по количеству тегов и получении только третьих трех строк.

во-первых, вы захотите использовать предложение Паскаля Мартина о дизайне таблицы.

Что касается поиска похожих статей, вот что поможет вам начать. Учитывая, что @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 имеют некоторое сходство.