我有一个系统,注册用户可以对图片进行投票/投票评论。它与Stack Overflow的投票系统非常相似。
我将投票存储在一个表中,其值如下:
vote_id | vote_comment_id | vote_user_id | vote_date | vote_type
现在我对以下内容的速度和效率有几个问题:
问题:一旦用户打开带有评论的图片页面,我就需要该用户已经对评论进行了UP / DOWN投票以显示它;评论旁边的“你投了票”或“你投了票”(在Stack Overflow中,投票图像突出显示)。
我可能的解决方案:现在,当我打开一个图片页面时,我会循环浏览每个评论,并循环浏览我的投票表并检查用户是否投票并显示状态(我将vote_user_id与用户的会话进行比较。
这有多高效?有没有人有更好的方法来解决这类问题?
答案 0 :(得分:2)
你没有提到你正在使用哪个数据库,但我假设有一些SQL变体。
因此,您可以执行类似
的操作,而不是遍历整个投票表select vote_type from vote_table where vote_comment_id = $commentId and vote_user_id = $userId
甚至更好,当您检索实际评论时,您可以left join
这样做
select c.*, v.vote_type from comments c left join (select * from votes where vote_user_id = $userId) v on v.vote_comment_id = c.comment_id
然后在显示循环中检查vote_type是否为null,up或down。如果你有1000条评论并且一次只显示10条,这可能效率较低,在这种情况下,第一种方法应该有所帮助。
[以上关于vote_type专栏的评论后编辑]
答案 1 :(得分:2)
你正在通过投票表?您是在将整个数据库读入内存然后循环读取它吗?
您是否尝试仅查询数据库中的相关数据?
SELECT vote_comment_id, vote_type
FROM vote
WHERE vote_user_id = 34513
AND vote_comment_id IN (3443145, 3443256, 3443983)
答案 2 :(得分:1)
如果要检索大量行,请尽量避免使用subselect。
select c.*, v.vote_type
from comments c
left join vote v
on v.vote_comment_id = c.comment_id
and v.vote_user_id = $userId
使用CASE语句显示/隐藏vote_type。
select c.*, CASE v.vote_user_id WHEN $userId
THEN v.vote_type /*compare vote_user_id with the user's session*/
ELSE null END AS 'votetype' /*hide vote_type */
from comments c
left join vote v
on v.vote_comment_id = c.comment_id
答案 3 :(得分:0)
对于用户投票的任何内容,即你是否需要一个列,即post_id?
您可以执行选择查询,查看当前帖子和用户是否存在行 - 如果返回行,则表示他们已投票。
实际上,我只是注意到vote_comment_id不是我读的那样(vote_comment)。
您只需检查行是否存在
答案 4 :(得分:0)
我的网站具有类似的逻辑。我没有跟踪个人投票(为此),我只有一个帖子(图像)表,一个投票计数和一个带有userid的文本字段:vote; userid:vote ... pairs,其中vote为+/-。这样我就不需要从巨大的投票表中选择,我还需要加载属于帖子的行。对“userid:”的简单字符串搜索将显示当前用户是否已投票。
需要ACID交易才能保持投票计数和投票文本字段一致。
答案 5 :(得分:-1)
我的解决方案是在登录会话时获取所有用户的投票。 将所有注释的ID提取到两个数组中:
$_SESSION['votes'] = array(
'up' => array(12, 854, 87, 78),
'down' => array(84, 32, 77)
);
当用户访问某个页面时,检查其ID是否存在于任何数组中。