我正在构建一个类似于 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
新闻源 View :
<% 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 %>
我想到的选项:
- 构建“Feed”表并使用后台作业为每个用户预处理大部分更新。最有可能是每小时一次的 cron。我会为每次更新存储完整的 HTML 代码。
- 保持初始结构,但单独缓存每个更新(现在我没有缓存)
- 切换到 MongoDB 以更快地访问数据库
我不得不说,我不是真正的专家,Rails 使第一步变得简单,但现在每个页面加载超过 150 个 SQL 请求,我觉得它已经失控,需要专家的观点......
你会怎么做?
感谢您宝贵的帮助,
最佳答案
您的代码并没有告诉我很多信息;我认为,如果您可以使用纯 JSON/SQL 来布置数据结构,那将会很有帮助。
无论如何,我会将每个用户的流序列化到 MongoDB。出于各种原因,我不会将 HTML 存储在数据库中(至少不会在软件的那个级别);相反,您应该将相关数据保存在一个(可能是多态的)集合中。获取新闻源非常容易,索引也很简单,等等。 View 结构基本上不会改变。如果您以后想要更改 HTML,那也很容易。
缺点是这会重复很多数据。如果人们可以有很多追随者,这可能会成为一个问题。使用用户 ID 数组而不是单个用户 ID 可能会有所帮助(如果所有关注者的信息都相同),但它也有局限性。
对于非常大的关联问题,只有缓存。按照我的理解,facebook 和 twitter 的神奇之处在于它们不会经常访问数据库并将大量数据保存在 RAM 中。如果您要关联数十亿个项目,即使在 RAM 中也是一项挑战。
应该连续而不是每小时更新一次。假设你的流量很大,每小时更新需要 30 分钟。现在,最坏的情况是 90 分钟。延迟。如果您及时处理更改,则可以将此时间缩短到 5 分钟左右。
您必须在某些时候加入假设,使用缓存和一些启发式方法。一些例子:
- 推文越新,它看到的流量就越多。它被转发的机会更高,而且被看到的频率也更高。将其保存在 RAM 中。
- 您 1991 年的 Facebook 时间线概览页面可能不会每天更改,因此这是长期输出缓存的候选页面。
- 当前的 Facebook 事件可能会进行大量写入。输出缓存在这里没有多大帮助。同样,该对象应保存在 RAM 中。
关于sql - 构建一个个性化的类似 Facebook 的新闻源 : SQL, MongoDB?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8491862/