(类似答案扬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
并保持更新。您只需更改查询即可使用它。但我不会开始非规范化,这是更多的代码和可以说是不成熟的优化。你的数据库用于跟踪这些信息;只要您复制它正在跟踪的信息,就会引入维护和同步问题。这些可能最终是合理的,但我不会开始认为我的数据库无法帮助我。如果在特定情况下加入是一个问题,则进行调整(如果您提前计划)并不是什么大问题。
感谢您的详细解答,它清除了很多东西。现在,我可以开始工作后,我的数据库管理技能刷了一下:) – mathon12
是否有可能修改查询的方式,将返回所有职位,即使那些尚未评级? (没有条目进入'userPostRatings'表。)在这种情况下,可能将'avg(r.rating)'设置为null?谢谢。 – mathon12
Doh!对不起,我不知道为什么我在那里使用内连接。只需将'inner join'更改为'left outer join'即可。 –