制作标签云 - 没有有效的标签来源

时间:2010-12-26 22:22:37

标签: php sql mysql tags distinct

所以我在我的数据库中索引了几千篇文章,我想根据有多少篇文章制作标签云,所以如果有1000篇文章有“全局”标签,那么它会比“国家“标签只有500左右的文章。这个概念似乎并没有让我感到困惑,除了我没有有效的标签来源。

查看每篇文章在数据库中都有一个标签字段,格式为: TAG1,TAG2,anothertag,againwiththetag

所以我打算进行DISTINCT查询以获取所有不同的标签,但我意识到这只会收集所有不同的标签排列。那么如何查询我的数据库中所有使用的不同标签及其数量呢?

谢谢你们。

2 个答案:

答案 0 :(得分:2)

  

查看每篇文章在数据库中都有一个标签字段,格式为:tag1,tag2,anothertag,againwiththetag

您的数据库未规范化。现在你必须付出代价来增加复杂性。

您必须扫描所有记录,抓取标记字段并总计总计。像这样:

$counts = array();
$result = mysql_query('SELECT tags FROM articles');
while ($record = mysql_fetch_array($result))
{
  $record_tags = split(',', $record['tags']);
  foreach ($record_tags as $tag)
  {
    ++$counts[$tag];
  }
}

现在$counts是一个数组,其标记为键,频率为值。

当然这给数据库带来了可怕的压力。更好的解决方案是规范化数据库:添加一个包含article_tagstag列的表article,其中article是指向articles表的外键。 tag可以是文字标记本身,也可以是tags表中的外键。如果要存储有关标签的元信息(描述,同义词等),则需要后者。

如果您已经这样做,代码将缩减为

$counts = array();
$result = mysql_query(
  'SELECT tag, COUNT(*) AS cnt FROM article_tags GROUP BY tag'
);
while ($record = mysql_fetch_array($result))
{
  $counts[$record['tag']] = $record['cnt'];
}

另外,请阅读数据库规范化,例如: Wikipedia: Database normalization,如果你还没有这样做的话。

答案 1 :(得分:2)

更改数据库模式以标准化标记应该是一个相当简单的练习。

您应该有一个标签表:

,而不是标签列
create table tags
(
  id int,
  name varchar2(50),
  ...
)

由于这种关系显然很多,你需要一个链接表:

create table articles_tags
(
    article_id int,
    tag_id
)

那么将当前标签转换为新类型应该相当容易,这里有一些伪代码!

1) tags = `select id,tags from articles`
2) for each tag in tags
3) if tag exists in `tags` get tag ID, else create row in `tags` and get tag id
4) using article id and tag id, create entry in articles_tags
5) alter table remove column tags!

这样,您只需运行以下内容即可创建标签云:

select t.name,count(*)
from tags t
inner join articles_tags at
on at.tag_id = t.id
group by t.name

通过自动完成功能,还可以更轻松地促进标签的重复使用。