Вопрос

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

  1. Каждая статья будет иметь полевые «теги», а теги будут в формате: «Tag1, Tag2, Tag3»
  2. Создайте другую таблицу под названием 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 пункт, для этой статьи будут две строки
    • Конечно, вы не хотите переоформивать статью, которую вы уже имели - что означает, что она должна быть исключена.
  • Но, как вы используете 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 имеют некоторые сходства.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top