【问题标题】:How to create randomized user ids with no repeats in MySQL?如何在 MySQL 中创建不重复的随机用户 ID?
【发布时间】:2019-01-24 21:20:15
【问题描述】:

我正在寻找一些关于效率和易于实施的见解,我有一个特定的目标。我有一个存储用户信息的 MySQL 表。创建帐户时,他们需要从 00000-99999 中获取自己的唯一随机 5 位代码。

这是我正在考虑的策略。其中一些似乎很难(对于像我这样的初学者),所以我只想咨询 Stack Overflow 的任何建议。

  • 使用从 00000 到 99999 的所有 5 位代码以随机顺序填充 company_id 列。这就是我迄今为止所做的。我的问题是,当有人创建帐户时,我需要查询数据库以找到第一个打开的行并获取与其关联的 5 位代码。到目前为止,我还没有弄清楚那部分。
  • 使用从 00000 到 99999 的所有 5 位代码按数字顺序填充 company_id 列。当有人创建帐户时,我会随机选择一个 open 行并获取与其关联的 5 位代码。这里的问题是选择一个打开的随机行。再说一次,我不知道我将如何做到这一点。
  • 在用户创建新帐户时创建 5 位代码,并在我的 user_data 中创建一个新行,该 5 位代码作为 company_id 列。这里的问题是创建新帐户的程序必须能够访问尚未使用的 5 位代码列表。我认为这可能是最好的选择,通过创建一个由 5 位代码 00000-99999 组成的数组,用 company_id 列中所有当前使用的 5 位代码填充一个数组,删除第一个数组中与第二个,然后从更改的第一个数组中选择一个随机的 5 位代码。

我要问的是,在创建新帐户时,哪个(这些策略或您自己的策略)首先在效率方面最好(不想让用户等待),其次,在易用性方面的实施。提前致谢!

【问题讨论】:

  • 为什么是随机的?为什么只有 5 位数字?
  • 我建议 3,有点。使用这么少的数字,您甚至可以在 sql 中动态生成它。请参阅此处第一个答案的直接链接:,但不要使用随机 stackoverflow.com/a/52098333/1007169 引用“生成 x 个随机数,然后选择一个不在表中的随机数:”。但是再次创建 00000-99999 而不是随机的。
  • @Uueerdo Random 因为人们会用它来登录,所以我宁愿他们不可预测。 5 位数,因为我可能不需要超过 100,000 个帐户。

标签: java mysql database performance random


【解决方案1】:

在如此小的范围内,如果您必须选择其中一个(而不是两者的组合),您最好保留一个未使用数字的列表。好吧,实际上这取决于您期望使用的上限与总可能值成比例。

如果您期望低密度,则生成一个随机数并与现有数字进行检查可能是您最好的选择。您的碰撞率将足够低,不会真正影响性能。

如果您期望高密度,保留未使用数字的列表并从中进行随机选择是更好的选择,因为替代方案可能非常糟糕。考虑最坏的情况,当只剩下一个数字时,使用低密度方法意味着您必须生成并丢弃该范围内的一半数字,以便有 50% 的机会找到未使用的数字。

最好的方法是在范围填充时切换方法;在使用 50% 时,您可能会在两个随机数生成中找到一个可用的数字;但在某个点满(当剩余的数字很少时),最好切换。

但最好的方法是不要对 id 值使用随机数;由于需要处理多个数据库客户端可能争用同一个未使用的公司 ID 的竞争条件,上述示例变得更加复杂。

【讨论】:

  • 听起来不错。我预计它可能永远不会达到 50% 的范围,所以听起来我将从您列出的第一个策略开始。谢谢。
【解决方案2】:

最简单的解决方案是将company_id 定义为自动递增的标识符列:

create table USER_DATA (
  company_id int not null auto_increment,
  .... other columns here
  primary key (company_id)
);

这是非常有效的,这对您来说似乎很重要。此外,生成一系列有保证的唯一数字是一种标准方法,从长远来看,这将使每个人的生活更轻松。确实company_id 是单调递增而不是随机分配的,但是随机ID 到底有什么好处呢?从字面上看,没有人关心 ID 是否是随机数。

【讨论】:

  • 谢谢。我会试试的。我想要随机 ID 的原因是我不想要这些 ID 的分配方式。它们在某些情况下用于登录,我宁愿让它随机。
  • 如果您需要前导零,请使用INT(5) ZEROFILL -- 这是(5) 的唯一用途。
【解决方案3】:

用随机顺序的数字构建表格。 (如果这很难,我会​​解释。)

BEGIN;
SELECT number FROM tbl LIMIT 1 FOR UPDATE;
DELETE FROM tbl WHERE number = << the value from the SELECT >>
COMMIT;

这将为您提供“下一个”号码,然后将其删除。事务是为了避免两个连接得到相同的号码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    • 2011-12-04
    • 2021-04-12
    • 2018-01-05
    • 2017-08-01
    • 2014-05-09
    • 2012-04-03
    相关资源
    最近更新 更多