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