记录不同自定义视图的计数

时间:2012-01-05 11:30:28

标签: mysql algorithm data-structures memcached redis

我正在尝试解决一个问题,即为列表视图获取不同自定义视图的记录数。自定义视图是一个用户定义的视图,它将添加一些标准。

示例:

  All Records View(3): {criteria : none}
   Name |email       |age  
   John |john@foo.com| 23
   Ann  |ann@foo.com | 20
   Jack |jack@foo.com| 13


  Kids View(1): {criteria : age<15}
   Name |email       |age  
   Jack |jack@foo.com| 13

  Foo Kids View(1): {criteria : age<15 and email contains('foo.com')}
   Name |email       |age  
   Jack |jack@foo.com| 13

如上例所示,根据标准,必须为每个视图计算视图计数。即使在用户选择特定视图之前,也会显示每个视图的计数。有多个用户正在查看记录的/添加/更新/删除记录。每次运行mysql查询以显示每个视图的计数可能非常密集和耗时,因为可能有数百万行。我曾考虑使用memcached或redis来存储视图的初始记录数和稍后在更改发生时更新它们。这里的问题是如何在运行时动态地找出哪个请求是哪个视图。

示例:如果从任何视图中删除'Jacks'记录,则必须在所有视图中减去,同样如果他的年龄更新为20,那么必须从孩子的视图和foo孩子的视图中减去计数。

欢迎任何关于如何解决这个问题的建议。

1 个答案:

答案 0 :(得分:1)

选项1:缓存。缓存记录在某处(memcached,redis)计数并定期运行cron作业以刷新计数器。如果您的计数器稍微不准确,请使用此方法。

选项2:在您的代码中存储路由逻辑。您的语言可能会或可能不会轻松。这就是它在Ruby中的样子:

class ViewMatcher
  def initialize
    @views = {'all' => lambda{|params| true },

              'kids' => lambda{|params| params[:age] && params[:age] < 15 },

              'foo kids' => lambda{|params| params[:age] && 
                                            params[:age] < 15 && 
                                            params[:email] && 
                                            params[:email].include?('foo')}}
  end

  def print_matching_views(params)
    puts "Matching views for query: #{params.inspect}"
    result = []
    @views.each do |k, v|
      result << k if v.call(params)
    end
    puts result
    puts ""
  end
end


vm = ViewMatcher.new

vm.print_matching_views :age => 10
vm.print_matching_views :age => 20
vm.print_matching_views :age => 10, :email => 'foo@example.com'
vm.print_matching_views :age => 10, :email => 'moo@example.com'

输出:

Matching views for query: {:age=>10}
all
kids

Matching views for query: {:age=>20}
all

Matching views for query: {:age=>10, :email=>"foo@example.com"}
all
kids
foo kids

Matching views for query: {:age=>10, :email=>"moo@example.com"}
all
kids