使用版本

版本 3.5.1

该问题是如何引起的

现象:使用mybatis-plus的id生成器由assign_id类型切换回auto类型时,再次生成的id起始值很大,导致大量id空间被浪费。 问题原因:调用mp的雪花算法id生成策略(assign_id),调整了数据库的主键起始值;切换为自增id(auto)主键生成策略时,因为之前雪花算法生成的id数值很大,导致产生了mysql的自增id断层现象。

重现步骤

最开始主键id自增初始值为6,后面使用雪花算法生成Long类型的id,然后切换回自增id生成策略之后出现了id序列过大的问题(mysql自增id断层)。 1. 全局配置:

  global-config:
    db-config:
      #主键类型(auto:"自增id",assign_id:"全局唯一id(雪花算法,Long或者String类型)",assign_uuid:"全局唯一id(
      #       无中划线的uuid)",input:"自行设置id,默认null",none:"不设置主键id")
      id-type: auto
      # 数据库大写下划线转换
      capital-mode: true
  1. 局部配置
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;

3.执行ID生成

    /**
     * @Description 自动生成主键id(雪花算法)
     */
    @PostMapping("/add")
    public void addUser(){
        User user = new User();
        user.setName("testIdType");
        userMapper.insert(user);
        System.out.println("主键id为:" + user.getId());
    }

MyBatis-Plus MybatisPlus切换Id生成策略导致自增id(Sequence)断层问题建议 4. 切换回自增id生成策略

    @TableId(type = IdType.AUTO)
    private Long id;

再次启动: MyBatis-Plus MybatisPlus切换Id生成策略导致自增id(Sequence)断层问题建议

新增一列的自增id的值已经被改变了,不是最开始的6了,而是在雪花算法的序列上自增。

建议

提供一个相关的注解或者方法,恢复有数据的mysql自增id断层问题(否则需要手动执行SQL),以节约id空间和重置id自增策略:

1. 查询出行数,并设置自增id初始值为行数+1;

select count(id) from user; 
alter table user AUTO_INCREMENT=8;

自动重置:通过Sequence实现类获取到行数,并将nextVal设置为为count(id)+1.

应用场景:已经存在关联外键的表数据或者不能变动的数据,但是需要节约id内存空间,一般为生产环境数据。因此提供一个保留原id只重置自增值的id切换方法,这种方式没有解决id断层问题,但是重置了自增id并保留了之前雪花算法生成的id。

2. 如果表中本来已经存在数据,并且有断号的现象。那么先删除主键再添加,重新设置自增长。

alter table user drop id;
alter table user add id bigint(20) primary key auto_increment FIRST;

这种方式解决了id断层问题,并且将所有的id重新有序排列了。 应用场景:在需要对更换id生成策略的所有数据进行id序列重置,但是不会删除掉原表的数据,一般为开发、测试和预生产环境。因此在保留表数据的前提下,重新排序所有id。 以上策略均为手动执行,可以利用代码实现,第二钟方式会改变原主键id,因此不建议在生产环境使用。

Comment From: miemieYaho

这和mp无关

Comment From: deepinsea

这和mp无关

是无关,可以提个pr在mybatis-plus提供自增id断层问题的解决方案吗?否则的话只能手动解决了