【问题标题】:How to design a MySql Table for a Tag Cloud?如何为标签云设计 MySql 表?
【发布时间】:2010-04-08 19:50:51
【问题描述】:

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

  1. 每篇文章都有“标签”字段,标签格式为:“tag1,tag2,tag3”
  2. 创建其他名为标签的表,其中包含字段: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 个“最常用标签”的最佳方法是什么?

【问题讨论】:

    标签: mysql database-design tag-cloud


    【解决方案1】:

    一般来说,对于这种多对多的关系,一共有三个表:

    • 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
    


    获得三篇“最相似”的文章意味着:

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

    未经测试,但一个想法可能看起来像这样:

    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
    

    基本上,你:

    • 为您的初始文章中出现的每个标签选择文章 ID
      • 由于存在内部连接,如果数据库中的一篇文章有​​ 2 个标签与 where 子句匹配,而没有 group by 子句,则该文章将有两行
      • 当然,您不想重新选择您已经拥有的文章——这意味着它必须被排除。
    • 但是,当您使用group by article.id 时,每篇文章将只有一行
      • 但您可以使用count 来查看每篇文章与最初的文章共有多少个标签
    • 那么,只需按标签数量排序,只得到第三三行。

    【讨论】:

    • 是的,但你没有回答我的主要问题,如何获得 3 篇最相似的文章?
    • @mfolnovich:我已经编辑了几次答案,以添加有关设计的更多信息;然后,看到你的评论,我重新编辑,添加一个可能的解决方案,以获得 3 篇最相似的文章。
    【解决方案2】:

    首先,您需要使用 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】:

      是的,但你没有回答我的主要问题,如何获得 3 篇最相似的文章?

      回答: 只需在合并表 (tags_articles) 中查找相同的标签 ID。收集它们并创建一个模式。

      例如: 第1条有标签:1,2 第 2 条有标签:2,3,4 第 5 条有标签:6,7,2 第7条有标签:7,1,2,3

      如果你想要文章 1 的 3 篇最相似的文章,你必须寻找标签 1,2。你会发现第 7 条最相似,第 2 条和第 5 条有一些相似之处。

      【讨论】:

        猜你喜欢
        • 2011-02-15
        • 1970-01-01
        • 1970-01-01
        • 2016-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多