如何为Tag Cloud设计MySql表?

mfo*_*ich 8 mysql database-design tag-cloud

我在我的网站上有文章,我想添加描述每篇文章的标签,但是我遇到了设计mysql表标签的问题.我有两个想法:

  1. 每篇文章都有字段"标签",标签格式为:"tag1,tag2,tag3"
  2. 使用字段创建名为tags的其他表:tag_name,article_id

因此,当我想要ID为1的文章的标签时,我会跑

SELECT ... FROM tags WHERE `article_id`=1;
Run Code Online (Sandbox Code Playgroud)

但是,我也想通过比较标签来了解3篇最相似的文章,所以如果我的文章有标签"php,mysql,erlang",还有5篇带有标签的文章:"php,mysql","erlang,ruby", "php erlang","mysql,erlang,javascript",我会选择1.,3.和4.,因为这3个标签与主文章大致相同.

还有一个问题,获得10个"最常用标签"的最佳方法是什么?

Pas*_*TIN 18

通常,对于这种多对多关系,有三个表:

  • " article"表
    • 主键= id
  • " tag"表
    • 主键= id
    • 包含每个标记的数据:
      • 例如,名字
  • 一个" 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
Run Code Online (Sandbox Code Playgroud)


获得三个"最相似"的文章意味着:

  • 选择包含第一篇文章标签的文章
  • 仅使用具有最重要数量的相同标签的那些

没有经过测试,但一个想法可能会是这样的:

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
Run Code Online (Sandbox Code Playgroud)

基本上,你:

  • 为您的初始文章中的每个标记选择文章ID
    • 因为有一个内连接,如果DB中的一篇文章有​​2个与该where子句匹配的标签,没有该group by子句,那么该文章将有两行
    • 当然,你不想重新选择你已经拥有的文章 - 这意味着它必须被排除在外.
  • 但是,正如您使用的那样group by article.id,每篇文章只有一行
    • 但是你可以使用count,找出每篇文章与初始文章共有多少个标签
  • 那么,这只是对每个标签数量进行排序,而只获得前三行的问题.