我有一个场景,我需要为单个订单生成 4 位确认码。 我不想只做随机代码,因为几乎同时生成两个精确代码的可能性很小。 有没有办法使用每个订单的 id 并从中生成 4 位代码? 我知道我最终会得到重复的代码,但这没关系,因为它们不会在同一时间生成。
您真的需要将代码基于 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% 时进行投诉。
如果您想避免重复,您无论如何都必须跟踪正在使用的代码,所以为什么不在一个地方管理所有这些呢?
如果你的订单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
。