雪花 ID 转 int64 位数字,长度是不固定的吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
dyllen

雪花 ID 转 int64 位数字,长度是不固定的吗?

  •  
  •   dyllen Sep 20, 2023 2874 views
    This topic created in 951 days ago, the information mentioned may be changed or developed.

    https://github.com/bwmarrin/snowflake

    https://github.com/sony/sonyflake

    用了两个库,生成的 ID 转 int64 纯数字长度都不一样,而且库的配置不同,长度也不一样。

    长度是不固定吗?

    生成是 18 个数字:

    import ( "time" "github.com/sony/sonyflake" ) var ( sf = sonyflake.NewSonyflake(sonyflake.Settings{ StartTime: time.Now().Add(-time.Hour), MachineID: func() (uint16, error) { return uint16(10), nil }, }) ) func GetNextSonyflakeId() int64 { flakeId, _ := sf.NextID() return int64(flakeId) } 

    生成的是 13 个数字:

    import ( "github.com/sony/sonyflake" ) var ( sf = snyflake.NewSonyflake(sonyflake.Settings{}) ) func GetNextSonyflakeId() int64 { flakeId, _ := sf.NextID() return int64(flakeId) } 
    15 replies    2023-09-21 17:56:40 +08:00
    a632079
        1
    a632079  
       Sep 20, 2023   1
    int64 固定占用 8 字节啊。雪花本质是利用 64bit 按自己需求划定区域(实际上符号位是不用的,大部分实现只用了 63 位),然后表示出 id 。你去纠结 int64 实际数字转成 string 后实际的 len 长度其实没有意义的。
    如果你想等长表示,应该考虑将他的 64bit 直接转成 string 。

    原理可以参考: https://pdai.tech/md/algorithm/alg-domain-id-snowflake.html
    Nazz
        2
    Nazz  
       Sep 20, 2023
    整数是不关心长度的, 你是不是转成字符串使用了
    Ericcccccccc
        3
    Ericcccccccc  
       Sep 20, 2023
    雪花是种思想, 你自己实现一个也行.
    jorneyr
        4
    jorneyr  
       Sep 20, 2023
    长度和配置+实现有关系,最大长度是 long 的最大值,应该有 19 位。
    heeeeeem
        5
    heeeeeem  
       Sep 20, 2023
    摘自自己写的文章:
    Twitter Snowflake 最初由 Scala 语言编写,Scala 为 JVM 系语言,其 long 类型的大小为 64bit ,所以 Snowflake 产生的 ID 也被设计为 64bit 大小。
    算法的核心思想是将 64bit 分段处理,64bit 的 ID 被分成了五段:
    1. 首位 1 个 bit ,首段,不使用,固定为 0 ,表示 ID 为无符号数
    2. 往后 41 个 bit ,毫秒跨度段,表示当前时间与初始设定时间相差的毫秒数,241 个毫秒数,可以使用 69 年
    3. 再后 5 个 bit ,数据中心段,表示数据中心的 ID ,可配置 25=32 个数据中心
    4. 再后 5 个 bit ,节点段,表示节点 ID ,每个数据中心可以配置 32 个节点
    5. 最后 12 个 bit ,序列号段,表示 0~4096 范围中的一个数,默认为 0 ,当在 1 毫秒内产生多个 ID 时,前面段的 bit 值是相同的,用这 12 个 bit 的值来区分,即在 1ms 内,支持产生 4096 个 ID

    当配置好数据中心 ID 和节点 ID 后,这两个段的值和首段的 0 是不会再变化了的,只有毫秒跨度段和序列号段值会发生变化。 如果 Snowflake 产生 ID 的间隔大于 1 毫秒,那么只有毫秒跨度段的值会发生变化;如果在 1 毫秒内要产生多个 ID ,则这一毫秒内只有序列号段发生变化( 0~4095 范围内递增)。最后将每次生成的 64bit 二进制数字转为 long 类型的十进制数字,得到最终的 ID 。
    fox0001
        6
    fox0001  
       Sep 20, 2023 via Android
    二进制位数,确定;十进制位数,不确定
    irrigate2554
        7
    irrigate2554  
       Sep 20, 2023
    StartTime: time.Now().Add(-time.Hour) 这种写法就完全错的,这样会产生重复的雪花 ID 的
    maocat
        8
    maocat  
       Sep 20, 2023
    @xausky 时间回拨问题?

    只要系统时间一直没问题应该不会有啥问题吧
    gps949
        9
    gps949  
       Sep 20, 2023
    因为 sonyflake 不是标准 snowflake 实现,而是经过了自定义。所以两者确实是不一样的。这你既然用到了 sonyflake 库,应该还是要读一读文档的。
    https://github.com/sony/sonyflake/blob/master/README.md

    另外,你不应该提问“长度是不固定的吗”,而应该提问“snowflake 和 sonyflake 包产生的 ID 长度不一样的吗”。
    再另外,因为 snowflake/sonyflake 都是基于时间戳的,所以如果你使用它们中的任一种,时间跨度超过一段时间,也会造成 ID 字符串长度不一样。
    irrigate2554
        10
    irrigate2554  
       Sep 20, 2023
    @maocat 重启程序就得出问题,时间位是用 now() - StartTime 填充的,以他这个写法重启程序就会从 1 小时重新计数,和之前的完全重复,正确的做法是所有地方都写一个固定时间,比如项目 2023 年开始,那就 2023-01-01 00:00:00.000 UTC ,或者直接写 0 库会用默认值也就是著名的 1970-01-01 00:00:00.000 UTC
    dyllen
        11
    dyllen  
    OP
       Sep 21, 2023
    @Nazz 是呀,想放在数据库做长度一样的 ID 的。
    dyllen
        12
    dyllen  
    OP
       Sep 21, 2023
    @xausky 这个是我测试的时候加的,测的时候改了时间看看结果,我用的时候没设置,用的库默认的。
    dyllen
        13
    dyllen  
    OP
       Sep 21, 2023
    @gps949 看过了,我看是固定 64 位的(库实际使用是 63 位),我转成十进制 int64 我以为也是固定长度的。
    gps949
        14
    gps949  
       Sep 21, 2023
    @dyllen
    转成十进制什么鬼,你是说转成十进制字符串吧?是固定 int64 类型存储,怎么会等同于固定长度呢? 64 个 0 的十进制是 0,60 个 0 、4 个 1 十进制就是 15 了。。。ID 前面是时间戳,跨度还蛮大的,肯定会在一些可能的位数间变化的。。。。snowflake 和 sonyflake 的时间戳和后面部分组成不一样,自然同一个时间生成的位数也可以不一样。。。
    dyllen
        15
    dyllen  
    OP
       Sep 21, 2023
    @gps949 库返回的就是是十进制的数,类型是 uint64 。那是我理解错了,我以为 64 个位全都会有值。
    About     Help     Advertise     Blog     API     FAQ     Solana     1051 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 58ms UTC 18:44 PVG 02:44 LAX 11:44 JFK 14:44
    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