5星评级系统mysql设置

时间:2012-02-10 06:25:17

标签: php mysql rating-system

好的,所以我知道还有其他问题。但我的有点不同......

我将会列出这些游戏的所有信息,我需要显示游戏的平均评分及其信息......

所以,我不想要2桌'游戏'和'games_ratings'因为那时我不能做一个简单的

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

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

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

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

4 个答案:

答案 0 :(得分:4)

我想在这里走出困境,因为我认为你不仅可能不熟悉mysql,而且对于建模也有点新意。

我会为这个想法推荐3个表。

  1. 用户表
  2. UserRatings表
  3. 游戏桌
  4. 用户表用于存储它。用户信息。可能是用户名,密码,名字,姓氏等。该表应该有一个主键。称之为UsersID。它应该自动递增并且对于每一行都是唯一的。

    接下来是游戏桌。在其中添加游戏名称。它也应该有一个主键。称之为GameID。

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

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

    此外,加入是你的朋友。做一点阅读。忽略外部,内部,交叉,左,右等,直到您熟悉简单直接连接的概念(并称之为很多东西)。

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

    干杯

    马特

答案 1 :(得分:1)

你说:

  

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

您必须已拥有用户表。 “记住”已经投票支持游戏的用户的唯一方法是通过FK到用户ID。现在,如果你有一个表混合用户和游戏,那么你的表将缺乏规范化,并将具有以下形式:

+--------+----------------+------------------------+--------+------+
| 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添加到用户分配给游戏的启动量。

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

嗯,我希望这有助于或指导您找到更好的解决方案。祝你好运!

答案 2 :(得分: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;

答案 3 :(得分:0)

您可以将games表中的平均值和总数保持不变。添加新评级时:

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

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

但是,为了记住谁投票决定了什么,最好的方法是将表格(useridgameidscore)保存为InnoDB表。