代码之家  ›  专栏  ›  技术社区  ›  Jonathan Allen

一种高效的评级系统MySQL表结构

  •  3
  • Jonathan Allen  · 技术社区  · 6 年前

    这篇文章是这个问题的后续: Best method for storing a list of user IDs .

    另外,当涉及到寻找游戏的平均评分和总投票数时,我应该分别使用以下两个查询吗?

    SELECT avg(vote) FROM votes WHERE uid = $uid AND gid = $gid;    
    SELECT count(uid) FROM votes WHERE uid = $uid AND gid = $gid;
    
    CREATE TABLE IF NOT EXISTS `games` (
      `id` int(8) NOT NULL auto_increment,
      `title` varchar(50) NOT NULL,
      PRIMARY KEY  (`id`)
    ) AUTO_INCREMENT=1 ;
    
    CREATE TABLE IF NOT EXISTS `users` (
      `id` int(8) NOT NULL auto_increment,
      `username` varchar(20) NOT NULL,
      PRIMARY KEY  (`id`)
    ) AUTO_INCREMENT=1 ;
    
    
    CREATE TABLE IF NOT EXISTS `votes` (
      `uid` int(8) NOT NULL,
      `gid` int(8) NOT NULL,
      `vote` int(1) NOT NULL,
      KEY `uid` (`uid`,`gid`)
    ) ;
    
    5 回复  |  直到 7 年前
        1
  •  6
  •   Uwe Mesecke    15 年前

    游戏的平均投票数: SELECT avg(vote) FROM votes WHERE gid = $gid;

    游戏的投票数: SELECT count(uid) FROM votes WHERE gid = $gid;

    0 你可以把它们变成无符号整数( int(8) unsigned NOT NULL

    如果您希望强制用户只能对游戏进行一次投票,那么请在上面创建一个主键 uid gid votes

    CREATE TABLE IF NOT EXISTS `votes` (
      `uid` int(8) unsigned NOT NULL,
      `gid` int(8) unsigned NOT NULL,
      `vote` int(1) NOT NULL,
      PRIMARY KEY (`gid`, `uid`)
    ) ;
    

    主键字段的顺序(第一个) 然后 )是重要的,因此索引按 基德 基德 . 如果要选择给定用户的所有投票,请添加另一个仅包含 液体 .

    我建议将InnoDB用于存储引擎,因为特别是在高负载设置中,表锁会破坏您的性能。为了提高读取性能,您可以使用APC、Memcached或其他工具实现缓存系统。

        2
  •  2
  •   Itay Moav -Malimovka    15 年前

    看起来不错。

    我会使用用户id&games_id代替gid和uid,后者听起来像全局id和唯一id

        3
  •  1
  •   dbr    15 年前

    编写一个脚本,生成100000个游戏、50000个用户和一百万张选票。可能有点过分,但如果你的查询不需要花几个小时处理那么多的项目,那就永远不会是问题

        4
  •  0
  •   Jan Jungnickel    15 年前

    到目前为止看起来不错。不要忘记索引和外键。根据我的经验,大多数问题并不是因为设计不够周密,而是因为缺少索引和外键。

        5
  •  0
  •   andyk    15 年前

    您可能需要添加一个 voted_on (DATETIME)列。这样,你就可以,比如说,看到游戏在某个时间段的趋势,或者万一有一天出现投票垃圾,你就可以准确地删除不需要的投票。