所以我在我的数据库中索引了几千篇文章,我想根据有多少篇文章制作标签云,所以如果有1000篇文章有“全局”标签,那么它会比“国家“标签只有500左右的文章。这个概念似乎并没有让我感到困惑,除了我没有有效的标签来源。
查看每篇文章在数据库中都有一个标签字段,格式为: TAG1,TAG2,anothertag,againwiththetag
所以我打算进行DISTINCT查询以获取所有不同的标签,但我意识到这只会收集所有不同的标签排列。那么如何查询我的数据库中所有使用的不同标签及其数量呢?
谢谢你们。
答案 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_tags
和tag
列的表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
通过自动完成功能,还可以更轻松地促进标签的重复使用。