关于数据库中Tag的设计

自己打算弄个小站,遭遇数据库Tag的设计问题,感觉自己的方案笨,发出来大家拍砖一下,顺便收集点意见。

谢谢。

小站的主体是类似Typecho这样的,主要文章发布的一个系统。由于需要为每个文章打上Tag,我经过Google,结合自己的实际(SQL不行,略懂吧),得出以下简单的方案:

CREATE TABLE IF NOT EXISTS `items` (
`id` int(11) unsigned NOT NULL auto_increment,
`tags` varchar(100) NOT NULL default '',
`text` longtext
) ENGINE=MyISAM  DEFAULT CHARSET=utf8  ;

这个是最简单的方法了,就是在每个文章的表项目中添加自己的Tag,这样从数据库中Select文章输出时候,最方便。

但问题来了,由于我需要设计一个类似SF的Tag标签汇总页面(比如这个关于PHP的 http://segmentfault.com/tag/php 的页面),就是列出所有有关PHP的文章时候,我的这个数据库方案显得很郁闷。而且我的SQL功底不是很好,连个查询Tag的SQL语句都只能用到like了。

考虑到范式,还有其他一些情况,我决定在第一种方案下将Tag独立出来,使用中间表将Tag与文章表连接起来,大体如下:

CREATE TABLE IF NOT EXISTS `items` (
`id` int(11) unsigned NOT NULL auto_increment,
`text` longtext
) ENGINE=MyISAM  DEFAULT CHARSET=utf8  ;
/**
    作为中间表让item和tag连接起来
*/
CREATE TABLE IF NOT EXIST `rel_item_tag` (
`id` int(11) auto_increment,
`item_id` int(11),
`tag_id` int(11)
);

CREATE TABLE IF NOT EXIST `tags` (
`id` int(11) auto_increment,
`tags` varchar(100) NOT NULL default '',
);

这样设计后,貌似还有问题的,考虑到我的要求,文章由作者发布,那么Tag也是作者给标上去的。而且我也是需要像SF这样整理每个Tag的介绍什么的,那用户随便弄个SSSSSSSSSS这样的Tag,然后使用/tag/SSSSSSSSSS 这样的网址来访问,这该情何以堪啊。

所以,我卡壳了,上来SF吐槽一下。唉,大学没有学好SQL的同学真伤不起啊!

看到SF的标签系统设计得挺好的,上来讨教一下。谢谢各位大神!

搜索来的资料参考:

阅读 17.1k
5 个回答

你需要搜索引擎。。。
TAG的具体名字只出现在展示的时候,具体到底层的搜索全部转换成数字。
在搜索引擎里,用多值整数这种东西来匹配。

其实你最后的问题就是想怎么过滤tag吧.这个我只想到了一个比较笨得方法,给tag加个状态属性,管理员审核通过才显示,不通过就仅仅是文章tag或者你直接删掉也行。感觉对付小站应该足够了吧,问题是不能实时就是了。
PS:个人觉得中间表和tag表是不是可以合到一个表中去呢?

在国内想要标签能比较好的利用,不被滥用,尤其是在非我们这样专业领域的网站,你需要做一些工作。

  1. 自己内置系统标签库
  2. 通过分词技术给没有设置标签的用户给与默认标签,或者推荐标签。
  3. 明显不对的标签可以过滤掉(过滤可以通过运营手段,也可通过技术手段),比如你说的SSSSSSSS

至于表的设计,node和tag建立manytomany就可以了。
你代码中的SQL中没有table name ?

个人觉得标签应该有两个用处:
1. 描述文章;
2. 聚合信息;

如果需要上面两个功能的话, 多一个关系对应表挺好的, 应该这么做!
只是描述文章的话, 完全可以把标签直接写在文章的表里面, 方便但是没有扩展性.

建议 tag 要严格维护, 如果是需要可以用来聚合文章信息的话.

新手上路,请多包涵

研究wordpress,必有所得。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏