У меня есть статьи о моем сайте, и я хотел бы добавить теги, которые опишут каждую статью, но у меня есть проблемы с дизайном mysql таблица для тегов. У меня есть две идеи:
Таким образом, когда я хочу теги для статьи с идентификатором 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 "наиболее используемых тегов"?
Обычно для такого рода отношений «многие ко многим» используются три таблицы:
article
»
тег
"
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
В основном вы:
where
, без группа по предложению
, для этой статьи должно быть две строки group by article.id
, в статье будет только одна строка
count
, чтобы узнать, сколько тегов у каждой статьи общего с исходной да, но вы не ответили на мой главный вопрос, как получить 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 имеют некоторое сходство.
Сначала 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