如何生成长度可自动递增、尽可能短且具备随机性的字符串类型主键
字符串类型自增随机主键实现方案
核心思路是自增数值基底 + 自定义Base编码的组合,可同时满足长度自动递增、尽可能短、带随机性三个要求。
实现步骤
1. 搭建全局唯一的自增数值基底
- 优先用数据库原生自增能力做基础:比如MySQL的
AUTO_INCREMENT字段、PostgreSQL的SEQUENCE对象,天然保证数值全局唯一、严格递增,不会出现重复冲突。 - 分布式高并发场景可以用雪花算法生成的64位整数作为基底,不需要依赖单库的自增序列,性能更高。
2. 自定义Base编码实现短字符串转换
你给出的26字母示例本质就是十进制自增数值转Base26编码的结果:数值越小字符串越短,数值增长到对应量级时长度自动+1,相比32位UUID长度可缩短50%以上。
为了满足随机性要求,不要用默认的顺序编码表:
- 先把用到的字符集(比如26个小写字母、大小写+数字共62个字符)的顺序完全打乱,生成自定义的编码映射表,比如26字母的编码表可以设置为
xmqkbrvtwpzshndgjlfceayiuo。 - 把自增基底的数值按照自定义编码表转成对应进制的字符串即可。
3. 可选增强随机性的操作
如果对不可预测性要求更高,可以在转编码前给自增数值加上固定的随机偏移量,进一步降低ID的可遍历性。
注意事项
- 自定义编码表一旦确定不能随意修改,否则会生成重复主键,也无法把现有主键反解析回原始数值。
- 字符集越大,相同数值对应的字符串长度越短:比如Base62编码的10位字符串就能覆盖2^60左右的数值,完全满足绝大多数业务的主键容量需求。
26字母编码示例
按乱序26字母编码表生成的ID规律如下:
- 1~26位自增数值对应1位长度字符串:
x、m、q、k...o - 27~702位自增数值对应2位长度字符串:
xx、xm、xq...oo - 703~18278位自增数值对应3位长度字符串:
xxx、xxm...ooo
完全符合你给出的示例规律,同时因为编码表是乱序的,外部人员拿到ID无法推测下一个ID的取值,满足随机性要求。
内容的提问来源于stack exchange,提问作者Richard Chen
相关产品推荐
相关产品推荐

