这篇文章是对这个已回答问题的跟进: Best method for storing a list of user IDs

我采纳了 cletus 和 Mehrdad Afshari 关于使用规范化数据库方法的史诗般的建议。以下表格是否正确设置以进行适当优化?我对 MySQL 效率有点陌生,所以我想确保这是有效的。

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

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`)
) ;

最佳答案

游戏的平均票数:SELECT avg(vote) FROM votes WHERE gid = $gid;
游戏的投票数:SELECT count(uid) FROM votes WHERE gid = $gid;
由于您不会拥有任何小于 0 的用户或游戏 ID,因此您可以将它们设为无符号整数( int(8) unsigned NOT NULL )。

如果您想强制用户只能对游戏进行一次投票,那么在 uid 表中的 gidvotes 上创建一个主键,而不仅仅是一个普通的索引。

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`)
) ;

主键字段的顺序(首先是 gid ,然后是 uid )很重要,因此索引首先按 gid 排序。这使得索引对于具有给定 gid 的选择特别有用。如果您想选择给定用户所做的所有投票,请仅使用 uid 添加另一个索引。

我会推荐 InnoDB 作为存储引擎,因为特别是在高负载设置中,表锁会降低性能。为了读取性能,您可以使用 APC、Memcached 或其他方式实现缓存系统。

关于php - 用于评级系统的高效 MySQL 表结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/621065/

10-12 22:23