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

数据库自增 id 不连续会有什么问题吗?

  •  
  •   Lexgni · 2022-12-06 14:52:57 +08:00 · 3609 次点击
    这是一个创建于 711 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如说事务回滚,硬删除等操作,造成的主键字段不连续会有什么影响吗?
    28 条回复    2022-12-08 11:22:30 +08:00
    git00ll
        1
    git00ll  
       2022-12-06 14:59:11 +08:00
    没啥问题
    wangxin3
        2
    wangxin3  
       2022-12-06 15:01:52 +08:00
    啥事没有
    brader
        3
    brader  
       2022-12-06 15:03:58 +08:00
    看你业务,你业务不依赖它的连续性来做逻辑,就没问题
    poorcai
        4
    poorcai  
       2022-12-06 15:08:33 +08:00
    没啥问题吧,而且数据库自增速度好像还挺快的,就是如果你在新增实体时,后面又需要用到这个实体的 id ,就得先保存再使用了
    Suomea
        5
    Suomea  
       2022-12-06 15:27:47 +08:00
    Datax 数据同步的时候是按照 id 切分任务的,不连续的话可能会导致切分不均匀,不能充分发挥多线程的优势加快数据同步。
    cloverzrg2
        6
    cloverzrg2  
       2022-12-06 15:31:47 +08:00
    From ChatGPT:
    如果数据库中的自增 id 不连续,可能会导致一些问题。首先,不连续的 id 可能会导致数据库中的数据无法按照预期的顺序进行排序。此外,不连续的 id 还可能会导致数据库查询操作变得更加复杂,因为在进行查询时需要考虑 id 的跳跃情况。最后,如果数据库中的 id 不连续,还可能会导致数据库中的数据缺失,因为在某些情况下可能会插入重复的 id ,从而覆盖原有的数据。总之,如果数据库中的自增 id 不连续,可能会导致一些计算和统计操作变得更加困难,并且可能会影响数据的完整性和准确性。
    jetyang
        7
    jetyang  
       2022-12-06 15:35:48 +08:00
    如果业务需要删除一些记录,那不就不连续了吗?挺常见的操作,没啥问题
    xyjincan
        8
    xyjincan  
       2022-12-06 15:45:07 +08:00
    pg 并行插入主键,好像返回的就是不连续的
    IvanLi127
        9
    IvanLi127  
       2022-12-06 16:00:00 +08:00
    直觉告诉我没啥问题,性能应该也没啥影响。
    victorc
        10
    victorc  
       2022-12-06 16:11:03 +08:00
    不连续无所谓,对于聚集索引,保持主键递增就行,不影响性能,auto_increment_increment 这个自增步长还可以配置成>1 的数

    中间因为删除出现个别空洞也没有关系
    wliansheng
        11
    wliansheng  
       2022-12-06 16:12:33 +08:00
    重要的是自增,连续不重要
    uSy62nMkdH
        12
    uSy62nMkdH  
       2022-12-06 16:38:20 +08:00
    可能会导致某些查询结果数据不均匀
    edis0n0
        13
    edis0n0  
       2022-12-06 18:48:58 +08:00
    我们商城订单号就是不连续自增的,每次增量不等概率随机 1~1000 (越小概率越高),主要是为了避免被推出实际订单量范围
    jiangwei2222
        14
    jiangwei2222  
       2022-12-07 08:30:39 +08:00 via Android
    没啥问题,为了避免分库主键重复,基本上都会把主键自增布长设置成 2 以上
    xingjue
        15
    xingjue  
       2022-12-07 09:17:32 +08:00
    递增就可以
    jiayouzl
        16
    jiayouzl  
       2022-12-07 10:27:55 +08:00
    当然没啥问题啊,比如我数据库某个表是自增 ID 的,我删除了一个数据,那自然就不会连续了,跟后续维护啥的没影响的.
    thtznet
        17
    thtznet  
       2022-12-07 15:24:21 +08:00
    最主要的严重后果:强迫症心理会出现问题
    wxf666
        18
    wxf666  
       2022-12-07 17:12:11 +08:00
    @cloverzrg2

    - 不连续的 ID 会顺序不正确?(变逆序 /随机顺序?)

    - 平时连续的 ID 会使什么查询操作变得便捷呢?(俩 uid 间有多少人?)

    - 自增 ID 为何会插入重复的 ID ,甚至覆盖原有数据呢?
    8355
        19
    8355  
       2022-12-07 18:24:36 +08:00
    @wxf666 #18
    自增就不会出现他说的问题
    我的单表 9 亿数据 月增量超 1 亿 没有任何问题
    只要是自增就不会 因为增量值是持续往后滚动的,因为我这边老系统单次任务平均写库 400 万 单条写库 1000 行 所以 id 跳很正常
    wxf666
        20
    wxf666  
       2022-12-07 18:36:50 +08:00
    @8355 我主要是没理解,为何『自增不连续 ID 』会出现 @cloverzrg2 说的『`ORDER BY` 失效』、『查询麻烦』、『出现重复 ID 』问题。。
    8355
        21
    8355  
       2022-12-07 18:51:23 +08:00
    @wxf666 #20 这 3 个问题不会出现 也不会出现任何意想不到的问题 除了 id 比预期值要大之外没有什么
    如果你的数据量够大主键直接用 bigint
    https://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html
    可以看官方文档了解下
    coder01
        22
    coder01  
       2022-12-07 18:51:56 +08:00
    正常应用没影响,骚应用就不好说了
    RedisMasterNode
        23
    RedisMasterNode  
       2022-12-07 20:23:01 +08:00
    怎么会没问题呢,业务量不大的话够用当然是 ok 的,业务数据如果多的情况下,回滚导致的空洞会让某个表的可承载数据量减少,例如实现的时候有 bug 或者漏洞,导致大批量的回滚操作,浪费了自增 id 的号段,原本能存放下 18446744073709551615 条数据(数字随便编的,记不准了)现在可能只能放下一半,或者更少的数据了。

    简单应用、维护得当可能看不出什么问题,但是稍不注意就会某一天突然报错了,而且是完全意料不到的,因为开发者可能认为比如 1 年内最多也就产生几千万条数据,单表轻轻松松,但是却因为实现上的缺陷导致 id 提前耗光,没加监控或者处理的话这在生产环境就是个 P0 的故障,数据写入不了。
    RedisMasterNode
        24
    RedisMasterNode  
       2022-12-07 20:25:22 +08:00
    我觉得最重要的是,开发者有没有意识到自增 id 的空洞存在、回滚会浪费多少的 id ,浪费之后的 id 字段类型( int 、bigint )是否还够用,评估好的话完全 ok 的,只是怕有些时候是意料之外的空洞。

    我们以前就出过这样的问题(意料之外,没监控,没及时发现),代价是把 id 列修改成字符串临时解决了(很不好的实践)。
    wxf666
        25
    wxf666  
       2022-12-07 20:38:44 +08:00
    @8355 所以感觉 6 楼像一本正经的胡说八道。。


    @RedisMasterNode 业务量大,一般至少会用 `bigint` 吧?`bigint` 不会这么容易用完吧。。
    RedisMasterNode
        26
    RedisMasterNode  
       2022-12-07 20:56:05 +08:00
    @wxf666 嗯其实我们故障的时候用的就已经是 bigint 了,正常用它确实是用不完的,但是那时候因为一些 bug ,浪费的 id 远比使用的多,频繁回滚等操作(具体忘记是什么不当操作了)导致浪费掉的 id 超过 99%,这是意料之外的事情了。

    咱意思就是,在代码有问题的时候,其实不能假设譬如浪费掉了一半的 id ,而是很可能回滚、浪费了上百个 id 才实际写入了 1 个 id

    这就跟内存泄露一样的,我认为我的应用只会使用 4GB 内存,我给机器分配了 32G 内存,就算应用有问题,开销翻倍,翻 3 倍,最多也就 10 多 GB 。但实际上不是,一旦出现意外,32G 内存全都用完了,自增 id 也是一个道理。
    WilliamYang
        27
    WilliamYang  
       2022-12-08 04:32:50 +08:00
    @edis0n0 请问你这个方案怎么做的,先预生成 id 吗?
    8355
        28
    8355  
       2022-12-08 11:22:30 +08:00
    @WilliamYang #27 分布式 ID 生成器
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2897 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 13:50 · PVG 21:50 · LAX 05:50 · JFK 08:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.