-1

好的,所以我知道还有其他类似的问题。但是我的有点不一样...

我将有一个包含这些游戏的所有信息的列表,我需要显示游戏的平均评分以及他们的信息......

所以,我不想有 2 个表 'games' 和 'games_ratings' 因为那样我就不能做一个简单的

SELECT id, name, howtoplay, otherinfo, avrating FROM games ORDER BY id;

如果有一个聪明的方法可以让我拥有一个 5 星评级系统,它会记住用户并可以在一张表中显示平均值以及信息。

我不太了解mysql的限制。我应该一次运行 2 个查询吗?我一直试图将每一页限制为只有一个查询。特别是如果我的第一个查询将加载 50 个游戏以显示有关信息。

我知道评分表就像用户 ID、歌曲 ID、评分的系统,您只需选择平均值。

4

4 回答 4

4

我将在这里冒险,因为我认为您可能不仅对 mysql 不熟悉,而且对建模也有点陌生。

我会为这个想法推荐 3 张桌子。

  1. 用户表
  2. 用户评分表
  3. 游戏桌

用户表用于存储它。用户信息。例如,可能是用户名、密码、名字、姓氏。该表应该有一个主键。称它为用户 ID。它应该自动递增,并且对于每一行都是唯一的。

接下来是游戏桌。把游戏名放进去。它也应该有一个主键。称之为游戏ID。

最后是 UserRatings 表。即使在关联类型表中,我也喜欢主键而不是复合键,但你也可以走这条路。说 UserRatingsId、Rating、InsertTimeStamp、UpdateTimeStamp。

现在为了存储平均评分,我可能会查看另一个表,或者在游戏表中放置一个评分列。每次在 UserRatings 表中插入/更新一行时,都会触发对该列或表的重构。

此外,加入是您的朋友。对它们进行一些阅读。忽略外部、内部、交叉、左、右等,直到您熟悉简单直接连接的概念(以及它被称为很多东西)。

尝试上面提供的一些答案和这个答案。我猜你的问题一旦开始玩就会更有针对性。

干杯

马特

于 2012-02-10T06:43:32.623 回答
1

你说:

如果有一个聪明的方法可以让我拥有一个 5 星评级系统,它会记住用户并可以在一张表中显示平均值以及信息。

您必须已经有一个用户表。“记住”为游戏投票的用户的唯一方法是通过对 userID 的 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:GameId 和用户)

+--------+--------+------+
| GameId |  User  | Vote |
+--------+--------+------+
|      1 | Timmy  |    3 |
|      1 | Martin |    5 |
|      1 | Moe    |    2 |
|      2 | Timmy  |    2 |
|      2 | Sonny  |    2 |
+--------+--------+------+

注意:我假设用户名是 PK,您也可以使用整数 userId,但这更容易阅读。

我知道加入很糟糕,但它们对你的帮助比对你的伤害更大。

现在,如何改进平均计算?好吧,对于每场比赛,您可以有另一列,例如TotalVotes将保留总票数,另一列SumVotes将保留该游戏所有投票的总和。因此,当投票的总数增加一时,TotalVotes 列并且您将用户分配给游戏的开始数量添加到 SumVotes。

然后,为了显示平均值,只需执行两个值的除法(这比连接和扫描表来重新计算要快得多。

好吧,我希望这可以帮助或指导您找到更好的解决方案。祝你好运!

于 2012-02-10T06:55:35.680 回答
0

我相信没有将这些信息存储在单个表中的有效方法。如果您希望它在一个表中只是为了查询简单,那么我建议您改用视图。

假设您有单独的游戏信息表和评级表(是的,您不喜欢的方法:))。像这样的东西:

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;
于 2012-02-10T06:29:32.483 回答
0

您可以将平均值和总数保留在games表中。添加新评级时:

UPDATE games SET
    average=((average*totalvotes)+{$votescore})/(totalvotes+1),
    totalvotes=totalvotes+1
WHERE id={$id}

这比每次重新计算平均值要有效得多。

但是,要记住谁对什么进行了投票,最好的方法是将 ( userid, gameid, score) 保存为表格的InnoDB表格。

于 2012-02-10T06:31:32.087 回答