我有以下表格;
CREATE TABLE IF NOT EXISTS `tags` (
`tag_id` int(11) NOT NULL auto_increment,
`tag_text` varchar(255) NOT NULL,
PRIMARY KEY (`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(11) NOT NULL auto_increment,
`user_display_name` varchar(128) default NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=10 ;
CREATE TABLE IF NOT EXISTS `user_post_tag` (
`upt_id` int(11) NOT NULL auto_increment,
`upt_user_id` int(11) NOT NULL,
`upt_post_id` int(11) NOT NULL,
`upt_tag_id` int(11) NOT NULL,
PRIMARY KEY (`upt_id`),
KEY `upt_user_id` (`upt_user_id`),
KEY `upt_post_id` (`upt_post_id`),
KEY `upt_tag_id` (`upt_tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
CREATE TABLE IF NOT EXISTS `view_post` (
`post_id` int(11)
,`post_url` varchar(255)
,`post_text` text
,`post_title` varchar(255)
,`post_date` datetime
,`user_id` int(11)
,`user_display_name` varchar(128)
);
我的想法是,我想使用最有效的方式为帖子和用户保存标签。只要我添加一个帖子,我就会在该帖子和用户之间传递几个标签。后来我希望能够为每个用户计算标签并发布。与Stack Overflow非常相似的东西。
我认为'tag_text'应该是唯一的?如果我每次提交新帖子以通过'tags'表检查标签是否已经存在时运行函数是否有效,如果是,则返回其'tag_id'以便我可以将其插入'user_post_tag'表
这可能是解决此类问题的不好方法。
欢迎所有建议。
答案 0 :(得分:2)
是的,你正在做的是最好的方法。您创建了一个n到m的关系,因为帖子可以有多个标签,同一个标签可以在多个帖子上。您不希望为每个帖子存储标记名称,因此您可以存储ID。
但是,你应该 - 对于同一个用户,存在多次相同tag_id
存储的减少量。如果用户有多个标签,那么它会严重影响您的服务器,并且您必须为每个标签执行SELECT count(...)
。你明白我在说什么吗?因为现在,如何获得用户A有多少次标签B?你必须SELECT count(*) FROM user_post_tag INNER JOIN tags ON (...) WHERE user_id=A and tag_id=B
。
我的建议是将user_post_tag
分成两个表:
user_tags
,要计算用户拥有此标记的次数,主键为user_id
和tag_id
,您将拥有count
字段,每当此用户使用标记发布新帖子时,只会使用count=count+1
进行更新。这样,您只需执行SELECT tag_text, count FROM user_tags INNER JOIN tags ON (...) WHERE user_id=A
即可选择给定用户的所有标记(使用次数)。您正在使用完全索引的查询。你不是要求MySQL过桌子,查找一堆行并计算它们,你告诉MySQL,在这张桌子和另一张桌子上这行,加入它们并快速交给我!post_tags
,要存储特定帖子的标记,主键为post_id
和tag_id
,不需要其他字段。我认为'tag_text'应该 独特吗?如果我运行有效 每次提交新内容时的功能 发布通过'标签'表来 检查标签是否已存在,以及是否存在 是的,返回它的'tag_id',所以我可以 将其插入'user_post_tag'表。
是的,它应该是独一无二的。如果标签不存在冗余并且必须执行SELECT ... count(*)以了解标签的使用次数,那么在插入和插入之前检查标签是否存在会更好。创建后的帖子比帖子选择要少得多,所以如果你必须在插入和选择之间进行查询密集,那么肯定会选择插入。
顺便说一下,如果你想计算有多少帖子有相同的标签,比如堆栈溢出,你需要另一个表,主键tag_id,然后像{{1每次帖子获得某个标签时,你都会增加user_tags
字段。
答案 1 :(得分:0)
嗯,如果您的标签都是唯一的,那么您在标签表中不需要tag_id和tag_text。只需使用tag_text并将其作为主键即可。然后查看REPLACE INTO(http://dev.mysql.com/doc/refman/5.0/en/replace.html)来处理新标签。
将标签与用户或帖子相关联? user_tags表和post_tags表。没有自动增量值只是具有user_id和tag_text或post_id和tag_text的复合键。我不知道你是否在查看user_post_tags表,以获得比使用帖子和用户加入post_tags表更高的性能。不过,“替换成”也应该是你的朋友。