3

我有一个带有多个计数器缓存的数据库架构。我不想让计数器缓存分布在许多表中,而是希望有一个名为 user_counters 的表,其中包含所有各种计数器缓存。我会使用如下方法从服务对象更新这些缓存:

def update_user_counter(column, user_id)
  UserCounter.increment_counter(column, user_id)
end

但是,关联用户的 UserCounter 记录很可能与用户的 ID 不同。我想做的是这样的:

def update_user_counter(column, user_id)    
  UserCounter.increment_counter(column, UserCounter.where('user_id = "#{user_id}"')
end

关于我如何做到这一点的任何想法?谢谢!!

4

1 回答 1

2

如果这些是与用户关联的 10 个属性,是否有任何理由不简单地将它们作为用户模型的一部分?如果是这种情况,下面的代码仍然可以工作(只需将方法作为 User 的一部分而不是 UserCounter)。

如果您想以自己的方式实现它,我会说首先确保您的user_counters表在 user_id 上有一个索引(因为 Rails 对于添加索引和 FK 是愚蠢的)。

然后,您可以这样做(将“列”作为符号传递):

class UserCounter < ActiveRecord::Base
  #other code

  def self.update_user_counter(column, user_id)
    counter = UserCounter.find_by_user_id(user_id)
    counter.update_attribute(column, counter.read_attribute(column) + 1)
    counter.save!
  end
end

在您的其他模型中:

class SomeOtherModel < ActiveRecord::Base
  #Model code

  def update_counter(user)
    UserCounter.update_user_counter(:this_column, user.id)
  end
end

此解决方案(或使用 update_counter 方法)都需要两次数据库命中,一次用于查找,一次用于更新。如果需要速度,可以直接用 SQL 编写:

query = "UPDATE user_counters SET #{column} = #{column} + 1 WHERE user_id = #{user_id};"
ActiveRecord::Base.connection.execute(query);

这假设在 上user_id是唯一的user_counters

于 2013-05-08T07:06:09.247 回答