【问题标题】:One big object or one small plus one big info object?一个大对象还是一个小加一个大信息对象?
【发布时间】:2011-04-27 17:44:39
【问题描述】:

对于 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 的数组吗?

我该怎么办?我还遗漏了问题的哪一部分?

谢谢你,

凯文

【问题讨论】:

    标签: ruby-on-rails postgresql activerecord oop


    【解决方案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 的简单练习

    【讨论】:

      猜你喜欢
      • 2020-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      • 2021-05-20
      • 1970-01-01
      • 2012-07-15
      相关资源
      最近更新 更多