0

我有一个场景,我需要为单个订单生成 4 位数的确认码。我不想只做随机代码,因为几乎同时生成两个确切代码的可能性很小。有没有办法使用每个订单的 id 并从中生成一个 4 位代码?我知道我最终会有重复的代码,但这没关系,因为它们不会在同一时间生成。

4

2 回答 2

2

您真的需要将代码基于 ID 吗?四位数字只为您提供一万个可能的值,因此您可以使用脚本将它们全部生成并将它们扔到数据库表中。然后在需要时从数据库中随机抽取一个,并在完成后将其放回。

您的代码表如下所示:

  • code: 编码
  • uuid:一个UUID,这里的NULL值表示这段代码是免费的。

然后,要获取代码,首先生成一个 UUID,uuid然后执行以下操作:

update code_table
set uuid = ?
where code = (
    select code
    from code_table
    where uuid is null
    order by random()
    limit 1
)
-- Depending on how your database handles transactions
-- you might want to add "and uuid is null" to the outer
-- WHERE clause and loop until it works

?你在哪里uuid)以安全的方式保留代码,然后:

select code
from code_table
where uuid = ?

?你又在哪里uuid)将代码从数据库中提取出来。

稍后,有人会将代码用于某事,然后您只需:

update code_table
set uuid = null
where code = ?

(代码在哪里code)将代码释放回池中。

您只有一万个可能的代码,即使您使用order by random().

这种方法的一个很好的优点是您可以轻松查看有多少代码是免费的;这使您可以每天/每周/每月/...自动检查代码池,并在免费代码的数量低于整个代码空间的 20% 时抱怨。

如果您想避免重复,则无论如何都必须跟踪正在使用的代码,那么为什么不在一个地方进行全部管理呢?

于 2011-07-26T00:49:01.420 回答
0

如果您的订单 ID 超过 4 位,理论上不可能不检查已生成值数组中的生成值,您可以执行以下操作:

require 'mutex'
$confirmation_code_mutex = Mutex.new
$confirmation_codes_in_use = []

def generate_confirmation_code
  $confirmation_code_mutex.synchronize do
    nil while $confirmation_codes_in_use.include?(code = rand(8999) + 1000)
    $confirmation_codes_in_use << code
    return code
  end
end

$confirmation_codes_in_use使用代码后记得清理。

于 2011-07-26T00:17:55.607 回答