我正在开发一个应用程序,我需要生成唯一的非顺序ID。我的一个限制是它们必须包含3个数字后跟2个字母(只有大约600k ID)。鉴于我的ID数量相对较少,我正在考虑简单地生成所有可能的ID,将它们混洗并将它们放入数据库中。因为,在内部,我将使用一个简单的,顺序的ID,所以很容易一次一个地将它们拔出来。确保我没有任何重复。
这不是一个非常令人满意的解决方案。有没有人有一种更有趣的方法从有限的池中生成唯一的ID而不是这种'抽奖'方法?
答案 0 :(得分:4)
您可以生成符合该标准的随机ID,执行数据库选择以查看它是否已存在,然后将其插入数据库以注意它已被“使用”。对于该方案的前25%(或约150k条目),生成新的随机ID应该相对较快。在那之后,它将花费更长的时间,你也可以预先填写表格以寻找免费的ID。
答案 1 :(得分:4)
使用有限群。基本上,取一个32位或64位整数,找到一个与你的整数的最大值互为的大数;将此数字称为M.然后,对于所有整数n,n * M将产生一个具有大量数字的唯一数字。
这样做的好处是您不需要预先填充数据库,也不需要运行单独的选择查询 - 您可以通过让n
只是一个插入语句来完成所有操作自动递增,并有一个单独的ID列,默认为n * M.
答案 2 :(得分:4)
这可以通过很多不同的方式完成,具体取决于您要优化的内容(速度,内存使用情况等)。
ID pattern = ddd c 1 c [0]
选项1(基本上类似于散列,类似于Zak):
1生成介于0和可能数之间的随机数(676k)
2-将号码转换为组合
ddd = random / (26^2)
c[0] = random % (26)
c[1] = (random / 26) % 26
3-查询DB是否存在ID并增加,直到找到空闲的为止。
选项2(线性反馈移位寄存器,请参阅wikipedia):
1-种子随机数范围(0,676k)。 (见下文为什么你不能用'0'播种)
2-通过将以下内容应用于当前ID号
num = (num >> 1) ^ (-(num & 1u) & 0x90000u);
3-跳过大于范围的ID(即0xA50A0 +)
4-将号码转换为ID格式(如上所述)
*您需要保存用于ID的最后生成的数字,但您不需要查询数据库以查看是否使用了该数字。由于LFSR的工作方式,此解决方案将枚举除[000 AA]之外的所有可能ID。
[edit]由于你的范围实际上比你需要的大,你可以通过在转换为ID之前减去1来获得[000AA]并使你的有效范围为(0,0xA50A0)
答案 3 :(得分:1)
根据您定义为顺序的内容,您可以在字母上选择某个起始点,例如“aa”,然后循环显示三个数字,因此它将是: 001aa 002aa 003aa
一旦你到达zz,然后增加数字部分。