如何在MySQL数据库中创建随机唯一(不重复)且固定长度(9位数字)的主键?

3

如题,如何创建一个9位数的主键,它必须是随机的、独一无二的,不重复,且范围在100000000到999999999之间?并且这种方法必须能够在Godaddy服务器上运行,因为Godaddy有许多限制。


1
Godaddy是无声之词。你不应该说它。(来自《星际迷航》的一集) - Drew
"Made it so"(作为标题)以及大多数《星际迷航:下一代》的剧集。 - tinonetic
3
让MySQL使用其自己的主键机制,然后你可以使用Hashids对返回的数字进行编码。这样不会改变MySQL的工作方式,也不会破坏成百上千个超级聪明的开发人员所做的工作,只需要使用不同的格式输出即可。 - N.B.
@N.B. 太棒了!但是我也必须使用 ID 作为输入,那时候我需要解码,你的想法应该使用什么机制? - chengwei
1
您可以使用我提供的库来对输入进行编码和解码。如果用户提供了正确编码的值,则它将能够成功解码。由于该库中的 salt、字母表和长度是可配置的,因此您可以在不涉及 MySQL 的情况下获得所需的结果。 - N.B.
显示剩余5条评论
2个回答

2
我只能想到两种可靠的创建唯一数字的方法。
  • 使用系统化的流程,例如自动递增,在这里您知道数字是唯一的。
  • 将生成的数字存储在表中。
您需要随机数,因此第一种方法可以使用伪随机数生成器进行应用。但第二种方法可能更容易实现。
它大致如下:
create table numbers (
    numberid int auto_increment primary key,
    n varchar(10) not null unique
);

然后您需要使用循环创建数字。直到成功为止,请执行以下操作:

insert into numbers (n)
    select cast((rand(*) * 900000000) + 1000000000 as varchar);

你可以使用last_inserted_id()来获取最近插入的数字。

但是如果两个人同时将数字插入数据库,它仍然唯一吗? - chengwei
@chengwei . . . 唯一约束是一个数据库保证。如果两个用户尝试插入相同的数字,则其中一个插入将失败。 - Gordon Linoff

1
如果伪随机对您来说可以接受,您可以创建如下触发器:
create trigger tr_setid before insert on mytable for each row
   set new.id := (
       select mod ((count(*) ^ 42) * 479001599 + 714320596, 900000000)+100000000
       from mytable);

如果您从表中删除记录,那么此系统就不好用了,因为该解决方案假定每次触发器运行时count(*)会增加一个。

乘数是质数而不是900000000的除数,确保在访问所有可能的数字之前不会生成重复的数字。

^运算符只是将count(*)映射,以使生成的系列稍微不那么可预测。

使用此触发器,表中的前10条记录将获得这些id值:

232387754
711389353
174384556
653386155
348394150
827395749
290390952
769392551
900374962
479376561

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接