比较ActiveRecord结果,仅使用各种结果

时间:2018-12-15 13:45:50

标签: mysql ruby activerecord redis

我当前需要通过Redis从站将数据同步到远程站点。数据存在于MySQL中。为此,我设计了一个类似于以下内容的同步脚本:

 MyTable
.select("id, first_name, status")
.find_each do |user|
    STDOUT.write(gen_redis_proto("SET", "users:#{user.id}",user.to_json))
end

这很好用。我将其通过管道传输到redis-cli --pipe(按照https://www.redis.io/topics/mass-insert),并插入到本地主服务器并同步到远程从服务器。

不幸的是,我有数千行,这使得同步非常大。我只想同步已更改的行,但是表中没有“ last_modified”或类似的值。

上面的代码循环运行,两次运行之间处于休眠状态,因此我可以存储先前的结果集并进行比较,但是我无法找到一种有效的方法来执行此操作。我在想类似下面的伪代码的东西:

 lines = [
    "{\"id\":123,\"first_name\":\"Jimmy\",\"status\":1}",
    "{\"id\":456,\"first_name\":\"John\",\"status\":2}",
    "{\"id\":789,\"first_name\":\"James\",\"status\":2}"
] 
previous_lines = [
    "{\"id\":123,\"first_name\":\"Jimmy\",\"status\":2}",
    "{\"id\":456,\"first_name\":\"John\",\"status\":3}",
    "{\"id\":789,\"first_name\":\"James\",\"status\":2}"
] 
varied_lines = diff(lines, previous_lines) # returns something like [0,1]
varied_lines.each do |line|
    this_line = line.to_a
    STDOUT.write(gen_redis_proto("SET", "users:#{this_line.id}",line))
end

我怀疑对数据的过多处理或比较会带来性能开销,而且我也不确定将这些数据进行比较以获得结果的最佳方法。

1 个答案:

答案 0 :(得分:0)

为什么不需要它,人力车gem可以让您轻松地将哈希添加到字符串中。我可能会做一些事情来存储和比较散列值,这将占用更少的空间。例子。

require 'rickshaw'

def diff(current, previous)
  current.select.each_with_index do |line, idx|
    previous_line = previous[idx]
    line.to_sha1 == previous_line.to_sha1
  end 
end

 lines = [ 
    "{\"id\":123,\"first_name\":\"Jimmy\",\"status\":1}",
    "{\"id\":456,\"first_name\":\"John\",\"status\":2}",
    "{\"id\":789,\"first_name\":\"James\",\"status\":2}"
]

previous_lines = [ 
    "{\"id\":123,\"first_name\":\"Jimmy\",\"status\":2}",
    "{\"id\":456,\"first_name\":\"John\",\"status\":3}",
    "{\"id\":789,\"first_name\":\"James\",\"status\":2}"
]

varied_lines = diff(lines, previous_lines)
varied_lines.each do |line|
    this_line = line.to_a
    STDOUT.write(gen_redis_proto("SET", "users:#{this_line.id}",line))
end