2009-12-20 129 views
1

我想为我写的论坛脚本中的每个帖子添加一个like/dislike-upvote/downvote-type功能(很像这里的SO)。我有两个难题试图弄清楚它是如何完成的:如何管理基于AJAX的“喜欢/不喜欢”功能?

1)我找不出一个可以高效完成的数据库模式。我可以使用单独的`likeordislike`表来创建用户和帖子之间的关系(xyz喜欢帖子#123),或者我可以在`posts`表中使用\'text \'类型的列,列出所有用户已经喜欢(或不喜欢)该帖子。后者当然意味着我必须解析用户ID的字段才能使用它。

2)确保用户不会喜欢/不喜欢一个帖子两次。

这可能是微不足道的,但我只能想到在服务器端进程上进行大量mysql调用的方式。谢谢。

回答

2

(类似答案扬Hanč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对于普通的没有任何等级任何发布。)

虽然这是一个连接,因为在的指标, 0表,这是一个相当有效的。

如果您发现一起被杀死你(非常高并发网站做),那么你可能需要去正常化一月建议的方式有点,通过添加平均得分列posts并保持更新。您只需更改查询即可使用它。但我不会开始非规范化,这是更多的代码和可以说是不成熟的优化。你的数据库用于跟踪这些信息;只要您复制它正在跟踪的信息,就会引入维护和同步问题。这些可能最终是合理的,但我不会开始认为我的数据库无法帮助我。如果在特定情况下加入是一个问题,则进行调整(如果您提前计划)并不是什么大问题。

+0

感谢您的详细解答,它清除了很多东西。现在,我可以开始工作后,我的数据库管理技能刷了一下:) – mathon12

+0

是否有可能修改查询的方式,将返回所有职位,即使那些尚未评级? (没有条目进入'userPostRatings'表。)在这种情况下,可能将'avg(r.rating)'设置为null?谢谢。 – mathon12

+0

Doh!对不起,我不知道为什么我在那里使用内连接。只需将'inner join'更改为'left outer join'即可。 –

3

制作一张单独的表格,您可以在其中跟踪谁喜欢什么,谁不喜欢。该表将被用于检查用户是否已经做了一些事情,所以你可以阻止他做两次。 然后添加另一个字段(如果您将有票)或两个(如果您将有喜欢/不喜欢),您将存储喜欢/不喜欢或得分的总数,所以你不必计算这个每当你显示帖子时当然,当有人对帖子进行投票时,您会更新本专栏(或专栏)。

而且不要打扰禁用投票链接。只要检查用户是否已经投票,当他点击链接并拒绝他投票,如果他已经投了一个。