好的,我知道还有其他类似的问题。但我的有点不同。。。
我要列出这些游戏的所有信息,我需要显示游戏的平均评分以及他们的信息。。。
所以,我不想有两张表"游戏"one_answers"游戏评分",因为那样我就不能做一个简单的了
SELECT id, name, howtoplay, otherinfo, avrating FROM games ORDER BY id;
如果有一个聪明的方法,我可以有一个五星评级系统,它可以记住用户,并可以在一个表中显示平均值和信息,那就太好了。
我对mysql的限制不太了解。我应该一次运行两个查询吗?我一直试图将每页限制为只有一个查询。尤其是如果我的第一个查询将加载50个游戏来显示有关的信息。
我知道这个系统的评分表是userid,songid,rating,你只需要选择平均值。
我将在这里冒险,因为我认为您不仅是mysql的新手,而且对建模也有点陌生。
对于这个想法,我推荐三张桌子。
- 用户表
- 用户评级表
- 游戏桌
Users表就是用来存储这些信息的。用户信息。例如,可能是用户名、密码、名字、姓氏。表应该有一个主键。称之为UsersID。它应该自动递增,并且对每一行都是唯一的。
下一张是游戏桌。在里面放一个游戏名称。它也应该有一个主键。称之为GameID。
最后是UserRatings表。我喜欢主键而不是组合键,即使在关联类型表中也是如此,但你也可以走这条路。说出UserRatingsId、Rating、InsertTimeStamp、UpdateTimeStamp。
现在,为了存储平均评级,我可能会查看另一个表,或者在游戏表中放一个评级列。每次在UserRatings表中插入/更新一行时,都会对该列或表进行重构。
此外,加入是你的朋友。读一读。忽略外部、内部、交叉、左侧、右侧等,直到您熟悉简单直联接的概念(以及它所称的许多东西)。
试试上面提供的一些答案和这个答案。我猜一旦你开始玩它,你的问题会更有针对性。
干杯
Matt
你说:
如果有一个聪明的方法,我可以有一个五星评级系统,它可以记住用户,并可以在一个表中显示平均值和信息,那就太好了。
您必须已经有一个用户表。"记住"投票给游戏的用户的唯一方法是通过对用户ID的FK。现在,如果你有一张混合了用户和游戏的桌子,那么你的桌子将缺乏规范化,并且将具有以下形式:
+--------+----------------+------------------------+--------+------+
| GameId | GameName | GameDescription | User | Vote |
+--------+----------------+------------------------+--------+------+
| 1 | Counter Strike | An addicting FPS game! | Timmy | 3 |
| 1 | Counter Strike | An addicting FPS game! | Martin | 5 |
| 1 | Counter Strike | An addicting FPS game! | Moe | 2 |
| 2 | Halo | Other addicting game | Timmy | 2 |
| 2 | Halo | Other addicting game | Sonny | 2 |
+--------+----------------+------------------------+--------+------+
这不是很正常化。。。事实上,你会让GameDescription和GameName到处重复!在这种情况下,您的PK将是GameId和User。你迟早会后悔的。所以,我们不要这么做。去这个:
游戏(PK:GameId)
+--------+----------------+------------------------+
| GameId | GameName | GameDescription |
+--------+----------------+------------------------+
| 1 | Counter Strike | An addicting FPS game! |
| 2 | Halo | Other addicting game |
+--------+----------------+------------------------+
用户(PK:用户)
+--------+
| User |
+--------+
| Timmy |
| Martin |
| Moe |
+--------+
投票(PK:游戏ID和用户)
+--------+--------+------+
| GameId | User | Vote |
+--------+--------+------+
| 1 | Timmy | 3 |
| 1 | Martin | 5 |
| 1 | Moe | 2 |
| 2 | Timmy | 2 |
| 2 | Sonny | 2 |
+--------+--------+------+
注意:我假设用户名是PK,你也可以使用整数userId,但这更容易阅读。
我知道加入很糟糕,但他们对你的帮助大于对你的伤害。
现在,如何改进平均计算?好吧,对于每个游戏,你可以有另一列,比如TotalVotes
,它将保存总票数,另一列SumVotes
,它将保留该游戏的所有票数之和。因此,当投票增加一次时,TotalVotes列将用户分配给游戏的开始次数添加到SumVotes中。
然后,为了显示平均值,只需对这两个值进行除法运算(这比连接和扫描表格来重新计算要快得多。
好吧,我希望这能帮助或引导你找到更好的解决方案。祝你好运
您可以将平均值和合计值保存在games
表中。当您添加新评级时:
UPDATE games SET
average=((average*totalvotes)+{$votescore})/(totalvotes+1),
totalvotes=totalvotes+1
WHERE id={$id}
这比每次重新计算平均值要有效得多。
然而,要记住谁对什么进行了投票,最好的方法是将(userid
、gameid
、score
)保存为InnoDB
表。
我相信没有有效的方法将这些信息存储在一个表中。如果只是为了简化查询而希望它在一个表中,那么我建议使用视图。
让我们想象一下,你有单独的游戏信息和评分表(是的,你不喜欢的方法:)。类似这样的东西:
CREATE TABLE games(id INT AUTO_INCREMENT, name VARCHAR(255), howtoplay TEXT, otherinfo TEXT);
CREATE TABLE ratings(game_id INT, user_id INT, rating INT);
然后您可以执行以下操作:
CREATE VIEW games_with_ratings AS SELECT id, name, otherinfo, howtoplay, AVG(rating) AS avrating FROM games LEFT JOIN ratings ON games.id=ratings.game_id GROUP BY id;
你只需要做一次,之后你就可以像在最初的问题中一样查询这个视图:
SELECT id, name, howtoplay, otherinfo, avrating FROM games_with_ratings ORDER BY id;