我正在构建类似Facebook的新闻源。这意味着它是从许多SQL表构建的,每个数据类型都有一个特定的布局。但是它的负载变得非常沉重,我希望能让它变得更加复杂......
这就是我现在所做的事情:
用户模型:
def updates(more_options = {})
(games_around({},more_options) + friends_statuses({},more_options).sort! { |a,b| b.updated_at <=> a.updated_at }.slice(0,35) + friends_stats({:limit => 10},more_options) + friends_badges({:limit => 3},more_options)).sort! { |a,b| b.updated_at <=> a.updated_at }
end
徽章数据示例:
def friends_badges(options = {:limit => 3}, more_options = {})
rewards = []
rewards = Reward.find(:all, options.merge!(:conditions => ["rewards.user_id IN (?)",self.players_around({},more_options).collect{|p| p.id}], :joins => [:user, :badge], :order => "rewards.created_at DESC"))
rewards.flatten
end
新闻源视图:
<% for update in @current_user.updates %>
<% if update.class.name == "Status" %>
<% @status = update %>
<%= render :partial => "users/statuses/status_line", :locals => {:status => update} %>
<% elsif update.class.name == "Game" %>
<%= render :partial => "games/game_newsfeed_line", :locals => {:game => update} %>
<% elsif update.class.name == "Stat" %>
<%= render :partial => "stats/stat_newsfeed_line", :locals => {:stat => update} %>
<% elsif update.class.name == "Reward" %>
<%= render :partial => "badges/badge_newsfeed_line", :locals => {:reward => update} %>
<% end %>
<% end %>
我想到的选项:
我不得不说,我不是真正的专家,Rails的第一步很容易,但现在每页加载超过150个SQL请求,我觉得它失控,需要专家的观点... < / p>
你会做什么?
感谢您的宝贵帮助,
答案 0 :(得分:2)
你的代码并没有告诉我很多;我认为如果你能用普通的JSON / SQL布局你的数据结构会很有帮助。
无论如何,我将每个用户的流序列化为MongoDB。我不会出于各种原因将HTML存储在数据库中(至少不是在软件的那个级别);相反,您应该将相关数据保存在(可能是多态的)集合中。获取新闻源很容易,索引很简单,等等。视图结构基本上不会改变。如果您以后想要更改HTML,那也很容易。
缺点是这将复制大量数据。如果人们可以拥有大量粉丝,这可能会成为一个问题。使用用户ID数组而不是单个用户ID可能有所帮助(如果所有关注者的信息相同),但它也是有限的。
对于非常大的关联问题,只有缓存。我理解它的方式,facebook和twitter的神奇之处在于它们不会经常访问数据库并在RAM中保留大量数据。如果您正在关联数十亿个项目,那么即使在RAM中也是如此。
更新应该连续写入,而不是每小时写一次。假设您有大量流量,每小时更新需要30分钟。现在,最坏的情况是90分钟。延迟。如果您及时处理更改,则可以将其缩短到5分钟。
你必须在某些时候抛出假设,使用缓存和一些启发式方法。一些例子: