自增列

    • 实现原理
    • 使用限制
    • 相关参数
    • 示例

实现原理

  • 每一个自增列使用一个全局可见的键值对用于记录当前已分配的最大ID
  • 为了降低分布式系统分配自增ID的网络开销,每个TiDB节点会缓存一个不重复的ID段
  • 当前预分配的ID段使用完毕,或重启,都会重新再次申请新的ID段

使用限制

  • 必须定义在主键或唯一索引的列上
  • 只能定义在整数、FLOAT或DOUBLE列上
  • 不支持与列的默认值同时指定在同一列上
  • 不支持使用 alter table 来添加auto_increment 属性
  • 需要通过session变量@@tidb_allow_remove_auto_inc控制是否允许通过alter table来移除auto_increment属性,默认不允许

auto_increment 属性

  • auto_increment: 用于自动填充默认字段值的属性
    • 处于性能考虑,auto_increment 编号会以批量的形式分配给每个TiDB 实例
    • 缓存批处理的大小可以通过auto_id_cache表选项控制
    • last_insert_id() 可以获得上次插入操作时使用的值

相关参数

AUTO_INCREMENT: 是⽤于⾃动填充默认字段值的属性

  • 出于性能考虑,AUTO_INCREMENT 编号会以批量的形式分配给每个 TiDB Server 实例
  • 缓存批处理⼤⼩可以通过 AUTO_ID_CACHE 表选项控制
  • LAST_INSERT_ID() 可以获得上次插⼊操作时使⽤的值
  • auto_increment_increment 每次增长多少,步长
  • auto_increment_offset 初始的数值是多少。
  • tidb_allow_remove_auto_inc 允许删除 列上的auto increment属性。默认是不允许。
tidb> show variables like 'auto_increment_%';+--------------------------+-------+| Variable_name | Value |+--------------------------+-------+| auto_increment_increment | 1 |# 每次增长多少,步长| auto_increment_offset | 1 | # 初始的数值是多少。+--------------------------+-------+
# tidb_allow_remove_auto_inc允许删除 列上的auto increment属性。默认是不允许。tidb> show variables like 'tidb_allow_remove_auto_inc';+----------------------------+-------+| Variable_name | Value |+----------------------------+-------+| tidb_allow_remove_auto_inc | OFF |+----------------------------+-------+1 row in set (0.01 sec)

示例

  1. 创建table
DROP TABLE IF EXISTS test.t1;CREATE TABLE test.t1 ( id int PRIMARY KEY AUTO_INCREMENT, from_port char(4));DROP TABLE IF EXISTS test.t2;CREATE TABLE test.t2 ( id int PRIMARY KEY AUTO_INCREMENT, from_port char(4)) AUTO_ID_CACHE 300;# 从300的基础上 开始增长 TiDB server 1 0-300 TiDB Server 2 301-600 
  1. 执行插入
/* Populate */INSERT INTO test.t1 (from_port) VALUES ('4000'), ('4000'),('4000');# id : 1,2,3/* Check value */select id, from_port from test.t1;/* Explictly assign value "7" to auto_increment column */insert into test.t1 values (7, '4000');# id: 1,2,3,7/* Check value */select id, from_port from test.t1;/* Relying on auto_increment values to assign values to new rows*/insert into test.t1 (from_port) values ('4000');insert into test.t1 (from_port) values ('4000');/* Check value */select id, from_port from test.t1;# id: 1,2,3,7,8,9注意:如果实在4000端口上执行,则结果是# id: 1,2,3,457
  1. 验证不同TiDB的缓存批处理大小
/* 在4000端⼝的tidb上插⼊数据 */insert into test.t2 (from_port) values ('4000');insert into test.t2 (from_port) values ('4000');# id: 1,2/* 在4001端⼝的tidb上插⼊数据 */insert into test.t2 (from_port) values ('4001');insert into test.t2 (from_port) values ('4001');/* 查询t2中的数据 */select * from test.t2# id: 1,2,301,302
  1. 验证不同TiDB中插⼊相同的id
/* 在4000端⼝的tidb上插⼊数据 */insert into test.t2 (id,from_port) values (90000,'4000');/* 在4001端⼝的tidb上插⼊数据 */insert into test.t2 (id,from_port) values (90000,'4001');

注意:这个会报错,提示插入的是重复值