2024-11-09  阅读(6)
版权声明:本文为博主付费文章,严禁任何形式的转载和摘抄,维权必究。 本文链接:https://www.skjava.com/mianshi/baodian/detail/1119967887

回答

自增 ID 指定义一个初始值,然后不停地往上加步长的数值字段。虽然自然数是没有上限的,但在计算机中会为字段定义类型,如 id int unsigned,int 占四个字节,那么它就有上限了。对于自增 ID 用完了的场景需要根据实际情况来分析:有主键和无主键

一、表定义的自增 id

当表定义的自增值达到上限后,再申请下一个 id 时,得到的值保持不变。故插入时会提升主键冲突错误。

create table t_test(
  `id` int unsigned auto_increment,
  `name` varchar(255) NOT NULL default '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB,auto_increment=4294967295;

int 占四个字节,unsigned int 能到的最大值是 232-1(4294967295)。通常情况下是够用了,但在互联网业务频繁插入删除的表中可能会被用完。此时可以将主键 id 创建为 8 个字节的 unsigned bigint

备注:单表 42 亿数据量也是惊人,老早就需要考虑分表了。

二、InnoDB 自增的 Row_id

另一种情况是建表时没有指定主键,那么 InnoDB 会创建一个不可见的,长度为 6 个字节的 row_id。InnoDB 内部维护**一个全局的 dict_sys.row_id 值,所有未定义主键的表都共享该 row_id(非单表独享),**每插入一行数据,当前的 dict_sys.row_id 值作为要插入数据的 row_id,并将 dict_sys.row_id 的值加1。row_id 具有如下特征:

  • row_id 的值范围为 0 到 248 - 1。
  • 当 dict_sys.row_id = 248 - 1,即 dict_sys.row_id 达到上限后,如果再有插入数据申请 row_id,下一个值就是0,如此循环
  • 在 InnoDB 中,申请到 row_id = N 后,会将这行数据写入表中;如果表中已经存在 row_id = N 的行,新写入的行就会覆盖原有的行