Сравнение результатов ActiveRecord и использование только разных - PullRequest
0 голосов
/ 15 декабря 2018

В настоящее время мне нужно синхронизировать данные через удаленный сайт Redis-Slave.Данные живут в 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), и он вставляется в локальный мастер и синхронизируется с удаленным ведомым устройством.

К сожалению, у меня несколько тысяч строк, что делает эту синхронизацию довольно большой. Iхотелось бы синхронизировать только те строки, которые изменились, однако в таблице нет "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 голосов
/ 15 декабря 2018

Почему вам это не нужно, камень рикши позволяет легко добавлять хэширование в строки.Я бы, вероятно, сделал что-то с хранением и сравнением хеш-значений, которые занимали бы меньше места.пример.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...