Mysql 在表中生成尽可能短的随机唯一字母字符串

Mysql 在表中生成尽可能短的随机唯一字母字符串,mysql,random,Mysql,Random,我在一个表中有很多记录,需要找到一种方法来分配一些唯一的代码 应该是独一无二的 应仅由小写字母组成(无数字),因此人们很容易使用语音字母在电话中提及记录代码,例如“嗨,我是约翰,我的代码是:阿尔法祖鲁威士忌狐步” 应该尽可能短 记录的过期日期约为2周,然后将其删除 新记录以每天数千条的速度不断创造。这张表每秒有几千次选择 理想情况下,这应该只在SQL中发生,这样我就可以将它添加到“before insert”触发器中,而不必使用selects来检查数据库中生成的应用程序端代码的唯一性,这正是

我在一个表中有很多记录,需要找到一种方法来分配一些唯一的代码

  • 应该是独一无二的
  • 应仅由小写字母组成(无数字),因此人们很容易使用语音字母在电话中提及记录代码,例如“嗨,我是约翰,我的代码是:阿尔法祖鲁威士忌狐步”
  • 应该尽可能短
记录的过期日期约为2周,然后将其删除

新记录以每天数千条的速度不断创造。这张表每秒有几千次选择


理想情况下,这应该只在SQL中发生,这样我就可以将它添加到“before insert”触发器中,而不必使用selects来检查数据库中生成的应用程序端代码的唯一性,这正是我现在要处理的,可能会带来很大的开销,我甚至不会在这里发布代码。

将整数主键转换为基数为26的数字。。。又名字母

0  becomes a
1  becomes b
25 becomes z
26 becomes aa
27 becomes ab
无需将此表示形式存储在数据库中,将其存储为整数,并在显示级别将其转换为字母

由于主键递增,这不是特别安全,因此可以猜测


如果希望代码过期,但不希望关联的数据过期,请创建第二个表,在创建代码时存储代码,并将外键返回到数据。使用插入触发器添加代码

CREATE TABLE user_codes (
    code     INTEGER PRIMARY KEY AUTO_INCREMENT,
    uid      INTEGER FOREIGN KEY users(id),
    created  TIMESTAMP 
);
如上所述,将整数代码转换为基数26,其中数字都是字母

这也保护了用户的主键,有人可能会用它做一些恶意的事情,最好不要泄露它

这也不是特别安全,可以猜测。您可以通过使用来改进它


如果它必须是随机的和唯一的,考虑使用一个调用来生成一个唯一的64位数字,它基本上是时间加上一个服务器ID。然后将它转换为基26,并将其转换为字母。不幸的是,这需要大约14个字母

…但因为它是基于时间的,所以也不是特别安全,可以猜测



最后,问问自己,代码是否必须是全局唯一的,或者是否足以让用户知道特定帐户的代码。例如,验证码。

您能告诉我们这些代码的用途吗?可能的重复。这些代码用于到达呼叫中心识别特定记录的代理。我们不希望他们必须记住或写下数字或字母数字代码。我们已经进行了测试,最好代码只由字母组成,并且尽可能短。发生这种情况的部分原因是电话线通常非常糟糕(在电话线上拼写一个10个字符的字母数字代码,带有噪音/延迟=>保证的烦恼和时间浪费)。这个问题不是重复的,前20-25个左右的搜索结果,所有其他问题都涉及UUID或随机整数等等。感谢随机整数可以表示为基数为26的小写字母序列。Base64表示包括数字,我们不需要数字,我们只需要数字。此外,如果我们将主键转换为base 26,我们将得到大约6个字符,这超出了我们的需要。在任何时候,我们的表中都有大约60000到100000条记录,因此我们不希望基于主键生成代码,因为代码太长。保持代码的私有性不是一个问题,这有单独的业务逻辑。uuid_short()返回的字符太多。代码在表中必须是唯一的,它与帐户或任何类似的东西都没有关联。顺便说一下,“我们的表中有大约60000到100000条记录”意味着这些是可搜索的记录。我们不会在过期时从表中删除它们,我们只是将状态字段更改为零并删除代码。添加此项作为澄清,以防您建议不时重置主键以保持ID较短…@NickM关于base64您是对的。。。这就是为什么我从来没有提起过。至于base 26,如果您只想使用小写字母,那么这是最好的选择。要覆盖100000条条目,您至少需要4个字母(
26^4
)。创建一个足够大的随机数,然后将其转换为以26为基数的字母。对不起,我的意思是以26为基数而不是以64为基数。。。输入错误或自动完成或两者兼而有之。谢谢。@NickM我相信你认为基数26必须像十六进制一样,0-9,然后用字母表示额外的16位数字。相反,放弃数字,只使用a-z作为数字。(我意识到我的示例中遗漏了0,并且我已经修复了它)