V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
drymonfidelia
V2EX  ›  程序员

有接入过 OAuth 的人应该都发现了, Google ID、Discord ID、Telegram ID 都是大整数,而且都和注册顺序没有直接关系(TGID 和注册顺序有一定关系,但不绝对)这些数据比大小没有意义,为什么不用字符串来存储?

  •  1
     
  •   drymonfidelia · 7 天前 · 4834 次点击

    大整数的兼容性更糟糕,像 TG ID 曾经就出现过因为超过了 int32 的最大值,大量 bot 、第三方客户端工作异常的事件。

    44 条回复    2024-06-21 15:02:57 +08:00
    alphaControler
        1
    alphaControler  
       7 天前 via Android
    跟数据库存储,和索引查表有关
    zmal
        2
    zmal  
       7 天前
    op 是用 oracle 的?
    nothingistrue
        3
    nothingistrue  
       7 天前   ❤️ 4
    第零,对外展示 ID ,跟其存储类型,没啥关系,超过 20 个长度的数字,它明显也得字符串存储。
    第一,亿级数据量,性能考虑的比重很大。
    第二,这些 ID ,并不是单纯的整数,往往都是同时兼顾离散性、顺序性、生成快速性的特殊序列。
    NessajCN
        4
    NessajCN  
       7 天前
    数字兼容性怎么可能比字符串更糟糕。数字你可以当它是个 int ,是个&[u8](两位两位取字节), 是个&[u8] (取 ascii ),字符串你只能存 &[u8] (ascii) 啊
    cccer
        5
    cccer  
       7 天前
    他数据库存的可能仍然是 16 进制的字符串,只是显示的时候转了 10 进制
    drymonfidelia
        6
    drymonfidelia  
    OP
       7 天前 via iPhone
    @NessajCN 很多编程语言 像 C++,在存储和操作大整数方面没有字符串友好、简单
    QAZXCDSWE
        7
    QAZXCDSWE  
       7 天前
    给你机会自辨真伪还说没意义?
    NessajCN
        8
    NessajCN  
       7 天前
    @drymonfidelia 那你当它是大整数来操作不就好了?
    NessajCN
        9
    NessajCN  
       7 天前
    @NessajCN
    @drymonfidelia 更正:那你当它是字符串来操作不就好了
    drymonfidelia
        10
    drymonfidelia  
    OP
       7 天前
    @QAZXCDSWE 什么意思?
    drymonfidelia
        11
    drymonfidelia  
    OP
       7 天前
    @NessajCN 像 C++这种语言,这么大的数转字符串都不方便
    635925926
        12
    635925926  
       7 天前
    什么是大整数,手机号是大整数吗?
    qping
        13
    qping  
       7 天前
    第三方的 ID 即使是个数字也要当字符串处理吧,万一那天它在数字后面加个字母呢
    drymonfidelia
        14
    drymonfidelia  
    OP
       7 天前
    @qping 但是他们返回的 JSON 里都是用 int 表示,而不是字符串
    @635925926 超过 Int32 最大值的数
    像 discordId 就是 18 位的
    Fikar
        15
    Fikar  
       7 天前   ❤️ 3
    InkStone
        16
    InkStone  
       7 天前
    @drymonfidelia 不方便在哪里?不管多少位的大整数,转字符串也就一两行代码的函数的事情啊。又不是让你去做大整数运算。
    NessajCN
        17
    NessajCN  
       7 天前
    @drymonfidelia 我懂了,你主要是来 diss C++ 而不是来 diss 大整数的....
    june4
        18
    june4  
       7 天前
    @drymonfidelia 难道 c++没有原生 64 位整数?
    nothingistrue
        19
    nothingistrue  
       7 天前
    @drymonfidelia #11 囧,搞了半天,你所说的大整数,只是 32-64 之间的整数。这在 Java 、.NET 等大多数语言中,早就是常态整数了。而编程语言之外的东西,除了 Mysql 这个用 Java 当底层的,压根就不关心你是 32 位还是 64 位,甚至是不是整数都不不安心,像 Oracle 和 json 就只有 number 。

    至于兼容性,这要遵循最大适应性原则和协商原则,现在更明显的是,你这个接受不了 int64 的 C++跑偏了。
    pkoukk
        20
    pkoukk  
       7 天前
    和索引有关,整型索引性能问题相对较少。
    longbowape
        21
    longbowape  
       7 天前
    看看雪花算法吧,现在主流的 id 生成都是 int64 了,哪还有抱着 int32 不放的
    Azure99
        22
    Azure99  
       7 天前   ❤️ 1
    您找的是不是:snowflake
    zxkxhnqwe123
        23
    zxkxhnqwe123  
       7 天前
    有没有可能是为了查询更快呢,字符串的话还得在转一下吧
    wysnxzm
        24
    wysnxzm  
       7 天前
    @nothingistrue #19 "除了 Mysql 这个用 Java 当底层的"这句话我没看懂
    montaro2017
        25
    montaro2017  
       7 天前
    @nothingistrue #19 MySQL 用 Java 当底层??
    jedihy
        26
    jedihy  
       7 天前
    超过 32 位就叫大整数,就得用字符串存了?你当 int64 不存在?
    kenvix
        27
    kenvix  
       7 天前
    我觉得用字符串才是真魔怔 UUID 也是魔怔
    Terryx
        28
    Terryx  
       7 天前 via iPhone
    字符串信息密度可太低了。问题是 int 和字符串有什么本质区别吗? id 这种东西是自定义数据数类型,唯一需要注意的是字节长度约定。字符串是不存在的,你用字符串去装任意长度的 int 也是可以的啊。
    vituralfuture
        29
    vituralfuture  
       7 天前 via Android   ❤️ 2
    因为比较的时候两个整数可以用一条机器指令,字符串只能逐字符比较,select 的时候快多了
    vituralfuture
        30
    vituralfuture  
       7 天前 via Android
    另外因为 id 超过 int32 最大值而无法工作这个问题,首先开发的时候就应该去查文档确定 id 的范围,telegram 应该是在服务端设计之初就确定了 id 的范围和类型
    tool2dx
        31
    tool2dx  
       7 天前
    为什么老是要和 int32 较劲,现代 C++支持一下 int64 和 int128 ,轻轻松松的好吧。
    flyqie
        32
    flyqie  
       7 天前 via Android
    你猜猜字符串和大整数哪个方便做索引和底层比较算法
    catamaran
        33
    catamaran  
       7 天前
    @kenvix 前公司的技术总监明确要求我们数据库主键用 uuid ,禁止使用 int ,搞得我们手忙脚乱。
    Rehtt
        34
    Rehtt  
       7 天前 via Android
    我记得 qq 号也是整数,甚至可以转成 16 进制登录
    kenvix
        35
    kenvix  
       6 天前
    @catamaran #33 合理怀疑这技术总监和数据库厂商有利益输送关系
    kenvix
        36
    kenvix  
       6 天前
    @tool2dx #31 Int128 那其实就是 UUID 了,但是很难想象是什么业务会有这么大的需求
    (不考虑把 UUID 按字符串存储的睿智操作...)
    iminto
        37
    iminto  
       6 天前 via Android
    和注册顺序有关啊,虽然不是递增的,但是有序啊
    drymonfidelia
        38
    drymonfidelia  
    OP
       6 天前 via iPhone
    @iminto 无序 我有一周内注册的两个 tg ,后注册的那个 id 反而更小
    nevermoreluo
        39
    nevermoreluo  
       6 天前
    1. 数据量层面存储 long long 都比 string 小太多,其实单凭这一点感觉存储上就没有存 string 的必要
    2. id 解析后是否顺序相关,和 id 展示出来大小可以不相关,id 直接用自增 int 的坏处是,业务模式容易被探知,例如单日新增用户等信息。当然长 id 也有坏处,例如 id 对用户不友好,需要专门的复制粘贴展示页等等
    3. 业务量大的时候,负载要分摊到很多机器上,新建一个数据时,分布式生成 id 尤为重要,分布式生成需要离散,足够快速并且全局唯一,全局唯一这个条件导致 id 就不会太短。
    4. C++该被吐槽,但是。。。C++存储大整数,没感觉有啥不友好的
    nothingistrue
        40
    nothingistrue  
       6 天前
    @catamaran #29
    @kenvix #31
    上了高层面,数据设计上就要区分事务性数据和分析性数据了。用于常用业务的事务性数据,数据量往往十万都到不了,这时候离散的 UUID 就是首选。偶尔数据量上去的事务性数据,比如 twitter 这种体量的用户,也是换用雪花 ID 来同时保持离散跟顺序,不搞顺序而不离散的数字。分析性数据,用 UUID 就不合适。
    kenvix
        41
    kenvix  
       6 天前
    @nothingistrue #40 但是事实上是,绝大多数业务的事务性数据都不需要 128bit 的 UUID ,即使是 twitter 用的也是 64bit 的雪花 ID
    drymonfidelia
        42
    drymonfidelia  
    OP
       6 天前
    @vituralfuture 这些 ID 是随机的,不是递增的,比较两个 ID 没有任何意义
    nothingistrue
        43
    nothingistrue  
       6 天前
    @kenvix #37 128bit 也就 16 字节,可以直接存储为二进制 16 字节,或者转储为 Hex 存储为字符串 32 长度/字节(绝大多数编码,英文数字都是单字节编码)。这大小在数据库场景中,从来都是忽略不计的。UUID 做主键的缺点从来不是占用存储,而是其不连续。另外,Int64 可不一定是 4 字节存储,因为数字在数据库中往往不是二进制,而是十进制存储的,比如 Oracle 。
    vituralfuture
        44
    vituralfuture  
       6 天前 via Android
    @drymonfidelia 业务也许不需要比较 ID ,但一般连接都是在 id 列进行连接吧,如果 id 列建索引,可以用归并连接速度快很多,常见的 B+树就需要属性支持比较
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3213 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:51 · PVG 18:51 · LAX 03:51 · JFK 06:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.