我有一个问答网站(类似SO)。我想实现这个条件:
条件:拥有至少125个信誉的用户可以投票否决。
我可以用两种方式实现这个条件:
服务器端:当用户登录时,我得到他的信誉并将其设置为$_SESSION['rep']
。然后在评论之前使用它
if( $_SESSION['rep'] >= 125 ) { /* can vote */ } else { /* cannot vote */ }
数据库端:我可以使用触发器并像这样检查:
IF ( SELECT 1 FROM user WHERE id = new.user_id AND rep < 125) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "cannot vote";
END if;`
我已经测试了他们两个,他们也工作。现在我想知道哪一种更常见、更标准?
就我个人而言,我一直在使用数据库端方法(不是通过使用触发器,而是通过在PHP中评论和检查用户信誉之前查询数据库)。它不会使表演太慢。
但是,如果您确实需要良好的性能,您可能会将用户信誉缓存在内存中(不要使用$_SESSION,这很容易导致不一致性问题)。使用Redis/Memcached怎么样?当用户登录时,将他/她的信誉放入缓存中。当用户的信誉在数据库中更新时,也要更新(使)缓存。当你需要弄清楚用户是否有投票权时,你只需要查阅你的缓存,不需要数据库查询。
附言:缓存的密钥应该看起来像user_rep_5
(其中5是user_id),而不是user_rep_xxxx
(其中xxxx是会话id)。我的意思是,缓存应该全局进行,以确保只有一个真实的来源,而不是将其与会话相关联。
在此步骤之前
if( $_SESSION['rep'] >= 125 ) { /* can vote */ } else { /* cannot vote */ }
如果您更新$_SESSION['rep']
并使用更新后的信誉进行检查,效果会更好。
在服务器端执行是一个更好的选择。当用户登录时,你可以获得他的声誉,只需要在他回答之前进行验证。
当您在数据库端执行此操作时,您将执行一个额外的调用,这也会让用户等待来自DB服务器的响应。这会减慢你的速度。