cache_fu的关联补丁(belongs_to, has_one)

本文探讨了通过引入Memcache来缓存频繁访问的数据库查询结果,以减轻数据库服务器的压力。特别关注了如何缓存简单的SELECT查询,并提出了针对关联查询的缓存策略。此外,还讨论了缓存的一致性和时效性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了缓解数据库服务器的繁忙状态,准备加入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的缓存方法,作者本人可以马上看到更新,而其他人是要过几分钟才可以看到更新的。这个是比较容易实现的,只要在集合缓存时设定好时限就可以了。值得考虑一下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值