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

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

  1. каждая статья имела бы поле "тегами", и теги будут в формате: "tag1, tag2, tag3"
  2. составьте другую таблицу, названную тегами с полями: tag_name, article_id

Таким образом, когда я хочу теги для статьи с идентификатором 1, я работал бы

SELECT ... FROM tags WHERE `article_id`=1;

Но, я также хотел бы знать 3 самых подобных статьи путем сравнения тегов, поэтому если у меня есть статья, которая имеет теги "php, mysql, erlang", и 5 статей с тегами: "php, mysql", "erlang, рубин", "php erlang", "mysql, erlang, JavaScript", я выбрал бы 1., 3. и 4., так как те 3 имеют большинство тех же тегов с основной статьей.

Также другой вопрос, что лучший способ состоит в том, чтобы получить 10 "наиболее используемых тегов"?

8
задан Gordon 16 March 2012 в 12:06
поделиться

3 ответа

Обычно для такого рода отношений «многие ко многим» используются три таблицы:

  • Таблица « article »
    • первичный ключ = id
  • Таблица " тег "
    • первичный ключ = id
    • содержит данные каждого тега: {{ 1}}
      • имя, например
  • Таблица " 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 article.id , в статье будет только одна строка
    • , но вы сможете использовать count , чтобы узнать, сколько тегов у каждой статьи общего с исходной
  • , тогда нужно всего лишь отсортировать по количеству тегов и получить только третьи три строки.
18
ответ дан 5 December 2019 в 08:51
поделиться

да, но вы не ответили на мой главный вопрос, как получить 3 наиболее похожие статьи?

Ответ: Просто поищите одинаковые идентификаторы тегов в объединенной таблице (tags_articles). Соберите их и создайте выкройку.

Например: Статья 1 имеет теги: 1,2 Статья 2 имеет теги: 2,3,4 Статья 5 имеет теги: 6,7,2 { {1}} В статье 7 есть теги: 7,1,2,3

Если вам нужны 3 наиболее похожие статьи для статьи 1, вам нужно искать теги 1,2. Вы обнаружите, что статья 7 наиболее схожа, а 2 и 5 имеют некоторое сходство.

0
ответ дан 5 December 2019 в 08:51
поделиться

Сначала off, вы захотите использовать предложение Паскаля МАРТИНА о дизайне таблицы.

Что касается поиска похожих статей, вот кое-что, что поможет вам начать. Учитывая, что @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
1
ответ дан 5 December 2019 в 08:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: