有什么基于短数字的唯一 id 生成器的实现? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
请不要在回答技术问题时复制粘贴 AI 生成的内容
tctc4869

有什么基于短数字的唯一 id 生成器的实现?

  •  
  •   tctc4869 Jul 7, 2021 5485 views
    This topic created in 1755 days ago, the information mentioned may be changed or developed.

    我目前看到的雪花算法生成的 id 基本都是长整型,有没有短数字唯一 id 生成,直接生成 int,比如 b 站 av 号之类的。既然是短数字的唯一 id 生成,那就不会应用到类似“订单 id 生成”等诸如 1 秒内生成几百几千个 id 的场景中,

    希望能在服务端内部生成,不用必须依赖数据库来生成 id,能控制长度(比如长度固定,或者数字长度不低于几位不高于几位之类的)

    有没有序无所谓,当然如果能选择无序模式或有序模式的话,那最好不过了。

    那么有哪些实现的呢,或者哪些工具类有这些功能了

    22 replies    2021-07-08 11:21:48 +08:00
    tabris17
        1
    tabris17  
       Jul 7, 2021
    有啊,数据库自增字段,或者其他全局计数器
    retanoj
        2
    retanoj  
       Jul 7, 2021
    时间戳够用么?
    wellsc
        3
    wellsc  
       Jul 7, 2021
    @tabris17 自增性能不太行
    rioshikelong121
        4
    rioshikelong121  
       Jul 7, 2021
    你搜 shortid 就出来了
    luman
        5
    luman  
       Jul 7, 2021
    @wellsc mysql 自增主键性能还是不错的
    liaohongxing
        6
    liaohongxing  
       Jul 7, 2021
    最类似下面这个,但还是偏长
    https://gitee.com/yitter/idgenerator
    tctc4869
        7
    tctc4869  
    OP
       Jul 7, 2021
    @liaohongxing 谢谢,js 的话,数字很长就得把数字转成字符串
    timethinker
        8
    timethinker  
       Jul 7, 2021
    给一条数据赋值 ID 一般代表这条数据具有生命周期,也就是实体,随机性的 ID 生成优点是速度快,但是一般都比较长,短且紧凑的 ID 一般需要有一个单独的地方进行维护管理,因为随机会有重复的风险,毕竟这个状态我们需要持久化。

    说一下我们之前做过的一个 ID 生成服务:不同实体的 ID,都是一个隔离开的空间范围,这个递增的空间范围需要由一个独立的服务来进行维护和管理。传入实体类型,也就是一个 Key 绑定一个 ID 的当前值,并告诉这个服务我需要多大范围的 ID,可以设计一个接口:

    (start, end) nextIdRange(key, size)

    其中 key (实体标识)和 size (获取多少个)为参数,用于获取一段 ID 范围,返回值 start 为起始值,end 为结束值。
    客户端获得以后就可以在这个范围内进行本地递增。需要注意的是,这个接口需要保证原子性,也就是并发的时候不会返回相同的数据,每一次调用都将会导致内部维护的当前 ID 值发生变化。

    客户端如果生成 ID 频繁,可以考虑优化为当剩余的 ID 快要耗尽时,另外起一个线程去预取下一批次的 ID 段(假设是跨网络的服务调用,ID 生成服务为一个独立的进程),保证 ID 生成不会受到获取 ID 这个操作的延迟影响,设置为多少合适则取决于实际的情况。
    liaohongxing
        9
    liaohongxing  
       Jul 7, 2021
    @tctc4869 你注意看文档,我说的很长是指和 B 站 BV 相比 ,他这个 避免了 js 的最大值 ,仔细看下 。
    zhaokun
        10
    zhaokun  
       Jul 7, 2021
    @tctc4869 前端当成字符串处理有啥问题呢?
    oddcc
        11
    oddcc  
       Jul 7, 2021
    还是要依赖 id 生成的服务的
    简单的设计可以考虑提前生成 id,放到库里
    服务端用的时候一批一批的取,只要取出来就认为是用掉了
    整体设计比较简单,好理解,也没有过多的依赖
    jslang
        12
    jslang  
       Jul 7, 2021
    自己生成呗,毫秒时间戳+2~3 随机数
    或者 21-0707-剩余(毫秒 /秒)+几位随机数
    kop1989
        13
    kop1989  
       Jul 7, 2021
    最简单的就是时间相关+随机。具体时间精度取多少,随机又取多长,要看你的目标压力而定。
    macttt
        14
    macttt  
       Jul 7, 2021
    增加一个服务实例分配号段吧,每个服务存一个 id 池譬如 1~1000,用完了之后到发号服务里再拿一段号段,以此类推。用发号服务来保证 id 不重复。如果需要标识实例编号的话,得在短 id 头部预留几位保存实例编号。
    zachlhb
        15
    zachlhb  
       Jul 7, 2021 via iPhone
    short uuid 就可以
    sakishum
        16
    sakishum  
       Jul 7, 2021
    Snowflake 雪花?
    libook
        17
    libook  
       Jul 7, 2021
    如果不担心被遍历的话,可以数据库自增。

    如果担心被遍历的话就用时间戳+随机数字再 HASH,只不过越短碰撞可能性越大。

    当然也可以数据库自增再加随机量的增量,然后再做个风控监测,如果某客户端短时间内访问了大量的无效 ID 就封掉。

    缩短 ID 的最重要的一步是做进制转换。
    自增是十进制,HASH 是十六进制,如果你大小写不敏感就一律转换成 36 进制,即 0-9a-z,如果大小写敏感就用 62 进制,0-9a-zA-Z,这个如果用 JS 的话可以直接 toString(进制数)。
    sighforever
        18
    sighforever  
       Jul 7, 2021
    又短又唯一,不用数据库记录一下不可能啊,最少需要保存一个已用的数据范围
    mxT52CRuqR6o5
        19
    mxT52CRuqR6o5  
       Jul 7, 2021
    把自增 id 用对称加密算法加密,就能获得随机(只要密钥不泄露对外就等于随机)不会碰撞的 id
    lix7
        20
    lix7  
       Jul 7, 2021
    从服务上线起的毫秒时间戳 + IP 前后 16 位异或 + 两位随机数
    应该是足够用了,如果再有碰撞的话,就依赖于重试去处理了
    find456789
        21
    find456789  
       Jul 7, 2021   2
    我知道有个 基于字母+数字 的 叫 hashid, 很多语言都支持
    sunmoon1983
        22
    sunmoon1983  
       Jul 8, 2021
    不知道京东的订单号是怎么得出来的,很短,纯数字
    About     Help     Advertise     Blog     API     FAQ     Solana     3278 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 71ms UTC 13:28 PVG 21:28 LAX 06:28 JFK 09:28
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86