我想在我正在撰写的论坛脚本中为每个帖子添加一个喜欢/不喜欢upvote / downovote类型的功能(很像SO中的那个)。我有两个困难试图弄清楚如何做到这一点:
1)我无法弄清楚有效地执行它的数据库模式。我可以使用一个单独的`likeordislike`表来建立用户和帖子之间的关系(xyz喜欢post#123),或者我可以在`posts`表中使用一个类型为''text \'的列列出所有用户喜欢(或不喜欢)这篇文章。后者当然意味着我必须解析字段以便userID使用它。
2)确保用户不喜欢/不喜欢帖子两次。
这可能是微不足道的,但我只能想到在服务器端进程上进行大量mysql调用的方法。感谢。
答案 0 :(得分:3)
制作一个单独的表格,您可以在其中跟踪谁喜欢什么,谁不喜欢。该表将用于检查用户是否已经执行了某些操作,因此您可以阻止他执行两次操作。 然后添加另一个字段(如果你有投票)或两个(如果你有喜欢/不喜欢)你将存储喜欢/不喜欢或得分的总量,所以你不必计算这个 - 每次显示帖子时都会飞。当然,当有人在帖子上投票时,你会更新这一列(或多列)。
不要打扰禁用投票链接。只需检查用户在点击链接时是否已经投票,如果他已投票,则拒绝投票。
答案 1 :(得分:2)
(JanHančič的答案类似,但我认为我对评级的看法不同......)
您最初想要存储喜欢/不喜欢的单独表格绝对是我要去的方式。我将索引放在两个主要列(玩家ID和帖子ID)上,这对下一位是至关重要的。
例如:
create table users (
userId varchar(254) not null,
-- ...
primary key (userId)
)
ENGINE=...;
create table posts (
postId int(11) not null,
title varchar(254) not null,
content text not null,
-- ...
primary key (postId)
)
ENGINE=...;
create table userPostRatings (
userId varchar(254) not null,
postId int(11) not null,
rating int(2) not null,
-- ...
)
ENGINE=...;
create index userPostRatings_userId on userPostRatings(userId);
create index userPostRatings_postId on userPostRatings(postId);
然后我使用连接查询(无论是在存储过程中,在代码中还是在视图中)来获取帖子信息,例如:
select p.postId, p.title, p.content, avg(r.rating)
from posts p
left outer join userPostRatings r on p.postId = r.postId
where p.postId = ?
group by p.postId;
(对于任何尚无评分的帖子,这将返回NULL
。)
虽然这是一个连接,但由于userPostRatings
表上的索引,它是一个非常有效的连接。
如果您发现联接正在杀死您(非常高的并发站点),那么您可能希望通过向posts
添加平均评级列并保持Jan建议的方式对某个位进行反规范化它更新了。您只需更改查询即可使用它。但我不会开始非规范化,它是更多的代码,可以说是过早的优化。您的数据库可以跟踪这些信息;一旦您复制了它正在跟踪的信息,您就会引入维护和同步问题。这些可能最终是合理的,但我不会开始假设我的数据库无法帮助我。如果在您的特定情况下加入是一个问题,那么进行调整(如果您提前计划)并不是一件大事。