论坛首页 编程语言技术论坛

cache_fu的关联补丁(belongs_to, has_one)

浏览 2343 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-09-08   最后修改:2008-11-15
为了缓解数据库服务器的繁忙状态,准备加入memcache。
"SELECT * FROM table WHERE table.id = value" 这样的简单检索占了全局的30%,把这样的检索进行缓存可以很大程度的减少访问数据库的次数。Place.find(id)以及account.place这样的关联,会产生上边的简单检索。

Place.find(id)可以简单的用Place.get_cache(id)代替。

belongs_to和has_one关联的对应,参考了 http://jack.iteye.com/blog/169736 和 http://groups.google.co.jp/group/acts_as_cached/browse_thread/thread/5fefb2d2355a5048 。

module ActiveRecord
  module Associations
    class BelongsToAssociation
      def find_target_with_cached_association
        # is the associated class using it's own id as it's cache id?
        if @reflection.klass.respond_to?(:get_cache) &&
          (@reflection.klass.cache_config[:cache_id] || :id) == :id
          @reflection.klass.get_cache(@owner.send(@reflection.primary_key_name))
        else
          find_target_without_cached_association
        end
      end
      alias_method_chain :find_target, :cached_association
    end

    class HasOneAssociation
      def find_target_with_cached_association
        # is the associated class using this class as it's cache id?
        if @reflection.klass.respond_to?(:get_cache)
          @reflection.klass.get_cache("#{@reflection.primary_key_name}:#{@owner.id}") {
            find_target_without_cached_association
          }
        else
          find_target_without_cached_association
        end
      end
      alias_method_chain :find_target, :cached_association
    end
  end
end 


需要注意的是,采用这种方法,对于从表记录,其实产生了2个缓存。例如,Account:id,Account:name:<name>。在释放缓存的时候需要注意。

has_many关联的也想进行缓存,现在最大的问题不是如何写入缓存,而是修改后如何释放。Place A修改的时候,如何把所有包含A的集合的缓存全部释放。缓存被要求及时更新。修改者本人相关的集合缓存的释放相对来说比较容易,可是他人的集合缓存呢?突然想到mixi的缓存方法,作者本人可以马上看到更新,而其他人是要过几分钟才可以看到更新的。这个是比较容易实现的,只要在集合缓存时设定好时限就可以了。值得考虑一下。
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics