一个大对象或一个小加一个大信息对象?

时间:2010-10-19 21:26:47

标签: ruby-on-rails postgresql activerecord oop

对于Ruby on Rails应用程序,我有这个Movie对象,它有几个属性。几乎每个页面都需要将一些电影与按收视率排序的这些电影的完整列表进行比较,因此我习惯于缓存这个大排序列表。这很有用,因为我可以直接使用这个电影列表及其所有属性,而无需任何其他数据库请求。

最近,这个名单变得越来越大,一大堆2500部电影就无法容纳1MB的Memcache块。

我想知道是否将此Movie对象拆分为较小的对象(id,created_at,updated_at,score,attributes_id)并将其属性外部化为另一个对象是一个好主意。我会根据分数排序较小的电影列表,但很多其他请求。

虽然我们在这里,为什么不缓存2500个整数的数组,用Ruby做数学并且只得到我们感兴趣的50部电影?它需要50个DB调用,还是我可以让PostGreSQL给我一组电影2,5,6,89,......和2467?

我该怎么办?我错过了问题的其他部分吗?

谢谢你,

凯文

1 个答案:

答案 0 :(得分:1)

为什么不加载你需要的东西,而不是从模型中剥离属性?在进行简单的数值比较时,直接使用数据而不是涉及模型通常对您有利。简单散列的存储要求远低于完整的ActiveRecord实例。

在这种情况下,select_all是您的朋友:

class Movie < ActiveRecord::Base
  def self.data_for(*ids)
    select_all(
      sanitize_sql([ "SELECT id, score FROM #{quote_table_name} WHERE id IN (?)", ids.flatten ])
    ).inject({ }) do |h, row|
      h[row[:id].to_i] = row
      h
    end
  end
end

这将产生一个看起来像这样的简单哈希:

Movie.data_for(2, 5, 6, 89, 2467)
# => { 2 => { :id = > '2', :score => '4' }, ... }

如果您希望根据需要将字符串转换为整数,则可以清理结构,这将进一步降低存储要求。您可以使用普通数字和简单的哈希值存储大量数据。

此时,在Memcache中存储此哈希是一个使用Rails.cache的简单练习