我正在研究PHP / MySQL评级系统。对于用户能够评价用户必须登录。每个用户都有一个唯一的“UID”。网站上会有多个评级实例(每个游戏一个,在我的情况下),我需要一种在MySQL行中存储UID列表的有效方法(评级系统的每个实例的评级表中有一个MySQL行) )保持一个谁投票的记录。
我在其他系统中看到列表存储在序列化的PHP数组中。每次用户投票时,序列化数组必须被提取,反序列化,插入新的UID,重新序列化数组,并且MySQL行是UPDATEd。每次加载页面时,该列表必须再次被反序列化并检查以查看查看页面的用户是否已经投票以确保用户不投票两次。
这似乎是低效和繁琐的。 MySQL是否具有内置列表功能以帮助此过程更高效?有没有更聪明的方法可以解决这个问题?
我考虑过一种可能的替代方法,即忘记序列化并将UID存储在MySQL数据库的TEXT类型字段中。我会在每个UID之后附加一些非数字字符(比如句号[。])。要添加用户条目,我只需将UID连接到TEXT字段的末尾,然后连接句点。当检查用户是否已经投票时,我可以“SELECT * FROM table WHERE votes ='%$ UID。%';”。这会更有效地工作还是有更优雅的方式来完成工作?
关于表格结构的后续帖子...... Efficient MySQL table structure for rating system
答案 0 :(得分: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");
...
等等。
不要加入数组并将其存储在单个列中。你这是对的。
答案 1 :(得分:4)
在规范化数据库中,您应该将其存储在联结表中:
UserRatings
-------------
RatingID int
UserID int
UserVote int
我不知道你的疑问是什么。根据应用程序的不同,这可能没有可接受的性能。但是,在任何一种情况下,我建议您仅在适当的情况下使用规范化方法,基准和非规范化。