ruby-on-rails - Ruby on Rails 中 Postgresql 的线性同余生成器,用于生成唯一的、不重复的随机数?

标签 ruby-on-rails ruby postgresql

我可以使用 LCG(又名线性同余生成器)为我的员工提供一个9 位数字、唯一但不重复的工作 ID。

该算法应使用 BSD rand() 公式,初始种子(状态 0)为 111,111,111,但将 mod 2^31 更改为 mod 999,999,937:

rand

但是我是否必须始终从最后添加的员工中检索工作 ID 才能计算下一个员工?

请帮忙!

最佳答案

Can I use LCG, aka Linear Congruent Generator, to give my staff a 9-digit, unique but non-repeating work ID.

这取决于你如何使用它。

如果您想为每个请求生成一个工作 ID,那么不,您不能,因为

LCGs are not suitable for parallel programming. Multiple threads may access the currently stored state simultaneously causing a race condition. In implementations which use same initialization for different threads, equal sequences of random numbers may occur on simultaneously executing threads. Random number generators, particularly for parallel computers, should not be trusted.

(参见 Wikipedia )

但是你可以预先生成一堆工作 ID,对于每个员工,只需将第一个未使用的工作 ID 分配给他/她即可。

例如,您可以使用 db/seed.rb 预先生成工作 ID(假设您有一个 AR 模型 WorkId)

db/seed.rb

total_work_ids = 10_000  # based on how many potential employees
state = 111_111_111      # the seed

total_work_ids.times do
  state = (1_103_515_245 * state + 12345) % 999_999_937
  WorkId.create(value: '%09d' % state)
end

更新

使用数据库存储工作 ID 可能仍然存在竞争条件,因为每次获取新的工作 ID 时,都会执行一个查询 (SELECT id, value FROM work_ids WHEREused = 0 LIMIT 1) 并需要一次更新(UPDATE work_ids SETused = 1 WHERE id = ?),它不是原子的。

我认为最好的解决方案是在 Rails 应用程序外部实现外部服务,该服务以先进先出的方式提供工作 ID。该服务应该很快,因为所有 Rails 线程/进程都会访问它并阻止它们。

我认为redis set是存储那些未使用的工作 id 的好地方,因为它确保其中元素的唯一性,并且它的 spop 是原子的。

关于ruby-on-rails - Ruby on Rails 中 Postgresql 的线性同余生成器,用于生成唯一的、不重复的随机数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36108955/

相关文章:

javascript - 为什么 Rails 默认不在 HTML 页面底部包含 Javascript 文件?

ruby-on-rails - 是否可以在 Google App Engine 上使用 Ruby/jRuby/Java?

ruby-on-rails - delayed_job 缺少方法

postgresql - 英雄数据库 :push Taps Load Error:

postgresql - 在 postgresql where 子句中使用驼峰式列

ruby-on-rails - 事件记录更新所有 JSON 字段

ruby-on-rails - 在 Rails 3.1 中,上传的文件应该存储在哪里?

带有 SQL 开发人员问题的 PostgreSQL

ruby-on-rails - 如何在 rails 中的 show table active admin 中添加新项目

c - Ruby C 扩展 rb_str_new2 似乎返回 false