2009-03-06 98 views
4

我正在研究PHP/MySQL评级系统。让用户能够评估用户必须登录。每个用户都有一个唯一的“UID”。在网站上会有多个评级实例(每个游戏都有一个实例),我需要一种有效的方式将UID列表存储在MySQL行中(每个评级系统实例的评级表中有一行MySQL行)保持已投票人的理货。存储用户ID列表的最佳方法

我在其他系统中看到列表存储在序列化的PHP数组中。每次用户投票时,序列化数组必须提取,非序列化,插入新的UID,将数组重新序列化,并且MySQL行是UPDATEd。每次加载页面时,该列表都必须再次被反序列化并检查以查看浏览该页面的用户是否投票,以确保用户不投票两次。

这似乎是一种效率低下和繁琐。 MySQL是否有内置列表功能来帮助这个过程更高效?有没有更聪明的方法可以解决这个问题?

我考虑过一种可能的选择,那就是忘记序列化并将UID存储在MySQL数据库的TEXT类型字段中。我会在每个UID后面添加一些非数字字符(比如说一个句点[。])。要添加用户条目,我只需将UID连接到TEXT字段的末尾,然后是句点。当检查用户是否已经投票时,我可以只是“选择*从表中WHERE votes ='%$ UID。%';”。这样做会更有效率吗?还是有更好的方法来完成工作?

后续行动后对表结构... Efficient MySQL table structure for rating system

回答

17

效率低下。你在关系方面的含义是用户和游戏之间的多对多关系。用户可以在许多游戏上投票。游戏可以被许多用户投票。解决方案是有一个连接表:

USERS (uid, name, ...) 
GAMES (gid, name, ...) 
VOTES (id, uid, gid, ...) 

其中uid和gid是外键返回到它们各自的表。

如果有人投票,请在VOTES中插入记录。

拿到票的列表游戏:

$get = mysql_query("SELECT * FROM votes WHERE gid = $game_id"); 
... 

要获得用户的投票名单:

$get = mysql_query("SELECT * FROM votes WHERE uid = $user_id"); 
... 

等。

不要加入数组并将其存储在单个列中。你是对的,以避免这种情况。

+0

看来你和Mehrdad提出了相同的方法。我这样做。我唯一关心的是VOTES表的大小。可以想象,该表中可能有<#游戏x#用户>投票。这应该让我的共享主机计划管理员感到害怕吗? – 2009-03-06 22:27:35

4

在规范化的数据库,你应该把它保存在一个路口表:

UserRatings 
------------- 
RatingID int 
UserID int 
UserVote int 

我不知道是什么您的查询。取决于应用程序,这可能不具有可接受的性能。但是,无论哪种情况,我都建议你采用规范化的方法,基准,并在适当的时候进行非规范化处理。