我正在开发一个应用程序,我需要生成唯一的非顺序ID.我的一个限制是它们必须包含3个数字后跟2个字母(只有大约600k ID).鉴于我的ID数量相对较少,我正在考虑简单地生成所有可能的ID,将它们混洗并将它们放入数据库中.因为在内部,我将使用一个简单的,顺序的ID,所以很容易一次一个地拔出它们并且确保我没有任何重复.
这不是一个非常令人满意的解决方案.有没有人有一个更有趣的方法从有限的池中生成唯一的ID而不是这个'彩票'方法?
使用有限群。基本上,取一个 32 位或 64 位整数,并找到一个与整数最大值互质的大数;称这个数字为 M。然后,对于所有整数 n,n * M 将产生一个具有很多数字的唯一数字。
这样做的好处是您不需要预先填充数据库,也不需要运行单独的选择查询——您可以在一个插入语句中完成这一切,只需让您n成为一个自动增量,并有一个单独的默认为 n * M 的 ID 列。
这可以通过很多不同的方式来完成,具体取决于您想要优化的内容(速度、内存使用等)。
ID 模式 = ddd c 1 c[0]
选项 1(本质上类似于散列,类似于 Zak 的):
1 生成 0 到可能性数 (676k) 之间的随机数。
2- 将数字转换为组合
ddd = random / (26^2)
c[0] = random % (26)
c[1] = (random / 26) % 26
Run Code Online (Sandbox Code Playgroud)
3- 查询数据库是否存在 ID 和增量,直到找到空闲的 ID 和增量。
选项 2(线性反馈移位寄存器,请参阅维基百科):
1- 种子具有范围 (0,676k) 内的随机数。(参见下文为什么不能使用“0”作为种子)
2- 通过将以下内容应用于当前 ID 号来生成后续随机数
num = (num >> 1) ^ (-(num & 1u) & 0x90000u);Run Code Online (Sandbox Code Playgroud)
3- 跳过大于范围的 ID(即 0xA50A0+)
4- 将数字转换为 ID 格式(如上所述)
*您将需要保存最后生成的用于 ID 的数字,但不需要查询 DB看看是否被使用。由于 LFSR 的工作方式,此解决方案将枚举除 [000 AA] 之外的所有可能的 ID。
[编辑] 由于您的范围实际上比您需要的要大,因此您可以在转换为 ID 之前通过减去 1 来返回 [000 AA],并使您的有效范围为 (0,0xA50A0]
| 归档时间: |
|
| 查看次数: |
1084 次 |
| 最近记录: |