这篇文章是对这个已回答问题的跟进: 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
表中的 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`)
) ;
主键字段的顺序(首先是
gid
,然后是 uid
)很重要,因此索引首先按 gid
排序。这使得索引对于具有给定 gid
的选择特别有用。如果您想选择给定用户所做的所有投票,请仅使用 uid
添加另一个索引。我会推荐 InnoDB 作为存储引擎,因为特别是在高负载设置中,表锁会降低性能。为了读取性能,您可以使用 APC、Memcached 或其他方式实现缓存系统。
关于php - 用于评级系统的高效 MySQL 表结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/621065/