5星级评级系统mysql设置

发布于 2025-01-04 09:46:49 字数 442 浏览 0 评论 0原文

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

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

所以,我不想有 2 张桌子“游戏” '和'games_ ratings',因为那样我就不能做一个简单的事情,

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

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

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

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

Ok so I know there's other questions like this. But mine is a little different...

I'm going to have a list with all the information of these games and i need to display the games average rating along with their info...

so, I dont want have 2 tables 'games' and 'games_ratings' because then i cant do a simple

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

it would be nice if there is a clever way I could have a 5 star rating system, that remembers users and can display an average value all in 1 table along with the information.

I dont know a lot about the limits of mysql. Should I just run 2 queries at once? Ive always tried to limit each page to only one query. especially if my first query will be loading 50 games to display info about.

im aware of the system where the ratings table is like userid, songid, rating and you just select the average.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

暮倦 2025-01-11 09:46:49

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

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

  1. 用户表
  2. UserRatings 表
  3. 游戏表

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

接下来是游戏桌。在里面输入游戏名称。它也应该有一个主键。称之为游戏ID。

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

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

另外,加入是你的朋友。阅读一些关于它们的内容。忽略外部、内部、交叉、左、右等,直到您熟悉简单直连接的概念(及其名称)。

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

干杯

马特

I am going to go out on a limb here as I think you may not only be new to mysql, but a bit new to modeling as well.

I would recommend 3 tables for this idea.

  1. Users Table
  2. UserRatings Table
  3. Games Table

Users table is used to store just that. User information. Possibly a username, password, first name, last name for example. The table should have a primary key. Call it UsersID. It should auto increment itself and be unique for every row.

The Games table is next. Put a game name in it. It should have a primary key as well. Call it GameID.

Lastly is the UserRatings table. I am a fan of primary keys over composite keys even in associative type tables, but you could go that route as well. Say UserRatingsId, Rating, InsertTimeStamp, UpdateTimeStamp.

Now to store the average rating I would look at another table possibly, or putting a rating column inside the games table. Every time you insert / update a row in the UserRatings table you fire off a refactor of that column, or table.

Also, joins are your friend. Do a bit of reading on them. Ignore outer, inner, cross, left, right etc until you are familiar with the concept of a simple straight join (and its called many things).

Try some of the answers provided above and this one. I am guessing your questions will be much more targeted once you start playing around with it.

Cheers

Matt

裂开嘴轻声笑有多痛 2025-01-11 09:46:49

你说:

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

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

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

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

You said:

it would be nice if there is a clever way I could have a 5 star rating system, that remembers users and can display an average value all in 1 table along with the information.

You must have a users table already. The only way to "remember" the user who has voted for a game is by a FK to the userID. Now, if you have one table mixing users and games then your table will lack normalization and will have the form:

+--------+----------------+------------------------+--------+------+
| 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 |
+--------+----------------+------------------------+--------+------+

And this is not very normalized... Actually, you're gonna have GameDescription and GameName repeated everywhere! In this case, your PK will be GameId and User. You'll regret this sooner or later. So, lets not go for that. Go for this:

Games (PK: GameId)

+--------+----------------+------------------------+
| GameId |    GameName    |    GameDescription     |
+--------+----------------+------------------------+
|      1 | Counter Strike | An addicting FPS game! |
|      2 | Halo           | Other addicting game   |
+--------+----------------+------------------------+

Users (PK: User)

+--------+
|  User  |
+--------+
| Timmy  |
| Martin |
| Moe    |
+--------+

Votes (PK: GameId and User)

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

Note: I'm assuming the username is the PK, you can use an integer userId too, but this was easier to read.

I know joins suck but they will help you more than they will hurt you.

Now, how can you improve the average calculation? Well, for each game you could have another column such as TotalVotes which will hold the total amount of votes and another column SumVotes which will hold the sum of all the votes for that game. So, when a vote is casted in increase by one the TotalVotes column and you add to SumVotes the amount of starts that the user assigned to the game.

Then, in order to display the average, just perform the division of both values (that's much faster than joining and scanning tables to recalculate this.

Well, I hope this helps or guide you to a better solution. Good luck!

未央 2025-01-11 09:46:49

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

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

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

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

You can keep the average and total in the games table. When you add a new rating:

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

This is far more efficient than recalculating the average every time.

However, to remember who voted on what, the best way is a table with (userid, gameid, score) saved as an InnoDB table.

我不在是我 2025-01-11 09:46:49

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

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

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;

I believe there's no efficient way of storing this information in a single table. If you want it to be in one table just for query simplicity then I'd suggest using a view instead.

Let's imagine you have separate tables for games info and for ratings (yes, the approach you don't like :)). Something like this:

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

Then you can do the following:

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;

You have to do it only once and after that you will be able to query this view just like you want in your original question:

SELECT id, name, howtoplay, otherinfo, avrating FROM games_with_ratings ORDER BY id;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文