我能用LCG,也就是线性同余生成器,给我的员工一个9位的,唯一的,但不重复的工作ID吗。
算法应使用BSD rand()公式,初始种子(状态0)为11111111,但将mod 2^31更改为mod 999,999,937
ruby-on-rails - 用于在Ruby on Rails中为Postgresql提供唯一,不重复的随机数的Linear Congruent Generator?-LMLPHP
但我是否必须总是从上次添加的人员中检索work ID来计算下一个?
请帮忙!

最佳答案

我能用LCG,也就是线性同余生成器,给我的员工一个9位的,唯一的,但不重复的工作ID吗。
这取决于你如何使用它。
如果您想为每个请求生成一个工作ID,那么不行,因为
lcg不适合并行编程。多个线程可能同时访问当前存储的状态,从而导致争用情况。在对不同线程使用相同初始化的实现中,在同时执行的线程上可能出现相等的随机数序列。不应信任随机数生成器,特别是并行计算机的随机数生成器。
(见Wikipedia
但您可以预先生成一组工作ID,对于每个员工,只需将第一个未使用的ID分配给他/她。
例如,您可以使用db/seed.rb预生成工作id(假设您有AR模型WorkId
分贝/种子.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 WHERE used = 0 LIMIT 1)和一个更新(UPDATE work_ids SET used = 1 WHERE id = ?),这不是原子的。
我认为最好的解决方案是在Rails应用程序之外实现一个外部服务,它以先进先出的方式提供工作id。这个服务应该很快,因为它被所有的Rails线程/进程访问并阻塞它们。
我认为redis set是存储那些未使用的工作id的好地方,因为它确保了其中元素的唯一性,而且它的spop是原子的。

关于ruby-on-rails - 用于在Ruby on Rails中为Postgresql提供唯一,不重复的随机数的Linear Congruent Generator?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36108955/

10-16 21:48
查看更多