【问题标题】:What would be the most effective way to insert tags into a table将标签插入表格的最有效方法是什么
【发布时间】:2010-01-05 22:27:38
【问题描述】:

我有以下表格;

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”应该是唯一的?如果我每次提交新帖子时都运行一个函数来检查标签是否已经存在,如果是,则返回它的 'tag_id' 以便我可以将其插入到 'user_post_tag' 表中是否有效.

这可能是解决此类问题的坏方法吗?

欢迎所有建议。

【问题讨论】:

  • 你会在完成后将它作为开源发布吗?带有“与 Stack Overflow 非常相似的东西”

标签: php mysql tags


【解决方案1】:

是的,你正在做的是最好的方法。您创建了一个 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 拆分为两个表:

  1. user_tags,要计算用户有多少次使用此标签,主键将是 user_idtag_id 并且您将拥有一个 count 字段,您只需使用 count=count+1 更新此用户每次带有标签的新帖子。这样,您只需执行SELECT tag_text, count FROM user_tags INNER JOIN tags ON (...) WHERE user_id=A 即可选择给定用户的所有标签(使用次数)。您正在使用完全索引的查询。您不是要求 MySQL 遍历表,查找一堆行并计算它们,您是在告诉 MySQL,在这张表和另一张表的这一行,加入它们并给我,快!
  2. post_tags,存储某个帖子的标签,主键是post_idtag_id,不需要额外的字段。

我想“tag_text”应该 独一无二?如果有效,我运行 每次我提交一个新的函数 发布到通过“标签”表 检查标签是否已经存在,如果 是的,返回它的“tag_id”,这样我就可以了 将其插入“user_post_tag”表中。

是的,它应该是独一无二的。最好在插入之前检查标签是否存在,如果不存在则插入,而不是冗余并且必须执行 SELECT ... count(*) 才能知道标签已使用了多少次。与帖子选择相比,帖子创建的频率要低得多,因此如果您必须在插入和选择时查询密集型之间做出选择,请务必选择插入。

顺便说一句,如果你想计算有多少帖子具有相同的标签,比如堆栈溢出,你需要另一个表,主键为 tag_id,然后,比如user_tags ,每次帖子获得特定标签时,您都会增加 count 字段。

【讨论】:

    【解决方案2】:

    嗯,如果您的标签都是唯一的,那么您不需要标签表中的 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 表加入帖子和用户的性能提高。不过,“替换成”在这里也应该是您的朋友。

    【讨论】:

    • 我建议坚持使用数字键。如果您将文本字段设置为唯一键,REPLACE INTO 技巧仍然有效,并且可以更轻松地重命名整个标签。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-02
    • 2018-10-08
    • 2010-12-11
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多