Rails 自动生成编码导入数据库 利用 Redis 筛选重复的主键值

hrz3424 · 2017年04月21日 · 最后由 hrz3424 回复于 2017年04月24日 · 2157 次阅读

文档等我下班之后编写,现在要搬砖了,呵呵! 求助大家代码出现不稳定性,现在不知道原因在哪儿,主键的重复也做判断,但是在插入数据库报错,主键重复

created_at = DateTime.parse(Time.now.to_s).strftime('%Y-%m-%d %H:%M:%S').to_s #Time.zone.now
     updated_at = created_at
     $redis_qrcodes = Redis::Namespace.new('qrcode', redis: Redis.new)
     $redis_qrcodes.del('code')
     @code_key = Qrcode.pluck(:code)
     $redis_qrcodes.sadd('code',@code_key) unless @code_key.empty?
     sql_line_array = []
     1.upto(number) { |i|
       tmp_code = Qrcode.generate_code(digit)
       while true do
         unless $redis_qrcodes.sismember('code', tmp_code)
           $redis_qrcodes.sadd('code', tmp_code)
           sql_line_array << "('#{tmp_code}','#{digit}','#{prefixion}', '#{webpage_jump}','#{created_at}','#{updated_at}')"
           CodeJob.set(wait: 1.minute).perform_later(tmp_code)
           break
         else
            p "------------出现重复编码---- #{tmp_code}-----------------"
           tmp_code = Qrcode.generate_code(digit)
         end
       end
      }
     puts '------------结束批量生成编码code---------------------'
     puts '------------开始批量导入数据库---------------------'
     data = sql_line_array.join(',')
     sql_line = "insert into qrcodes (code,digit,prefixion,webpage_jump,created_at,updated_at) values  #{data}"
     begin
        ActiveRecord::Base.connection.execute(sql_line)
        puts '------------批量编码code成功导入数据---------------------'
     rescue ActiveRecord::RecordNotUnique => e
       puts '------------自动生成编码异常重新开始---------------------'
        Qrcode.generate_qr(digit,number,prefixion)
     end
     puts '------------结束批量导入数据库---------------------'
     return ''
   end

   def self.generate_code(digit)
     code = [*('a'..'z'),*('A'..'Z'),*(0..9)].shuffle[0..digit].join
   end

最后通过 benchmark 测试出现不稳定,之后查看了 code 的字段类型, 发现用 string varchar(10) 这个是问题的所在地,改用 binary 类型二进制就可以解决

会并发访问吗?如果同时在生成,$redis_qrcodes.del('code') 直接就把之前已经部分生成的给删掉了。

$redis_qrcodes.del('code') ,这个就是删除以前的,这个功能不是长期使用的,所以没有并发问题,

能不能用 markdown 语法,这样手机看不清

只是批量任务的话没有必要用 redis

ruby 标准库里面有 Set, 3000 个一次的话放到 Array 里面再 uniq 也没问题吧

code 中的字符必须是大小写加数字这个格式吗?

你的主键是 id 还是 code ?

lithium4010 回复

这个是通过 redis 筛选出重复主键的,不是为生成一组不重复的数据的,我生成的数据一次性的提交到数据库的,这个效率还是可以的。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号