自增ID实现原理:
- 每个自增列使用一个全局可见的键值对用于记录当前已分配的最大ID;
- 为了降低分布式分配自增ID的网络开销,每个TiDB节点会缓存一个不重复的ID段;
- 当前预分配的ID段使用完毕,或者TIDB重启的时候就会重新申请新的ID段;
自增ID使用限制
- 必须在主键或者唯一索引列上
- 只能定义在类型为整型、FLOAT或者DOUBLE的列上
- 自增列不支持DEFAULT定义
- 不支持使用LATER TABLE增加AUTO_INCREMENT属性
- 默认不允许移除AUTO_INCREMENT属性,可以通过@@tidb_allow_remove_auto_inc来控制是否允许删除自增属性;
- 可以保证自增不唯一,无法保证顺序
AUTO_RANDOM用于解决聚簇表大批量写入数据时,因含有整型自增主键而产生的热点问题
mysql> create table t(a bigint primary key auto_random);
Query OK, 0 rows affected, 1 warning (0.28 sec)
mysql> insert into t values(),(),(),();
Query OK, 4 rows affected (0.05 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from t;
+---------------------+
| a |
+---------------------+
| 1441151880758558725 |
| 1441151880758558726 |
| 4899916394579099655 |
| 4899916394579099656 |
| 6052837899185946625 |
| 6052837899185946626 |
| 6052837899185946627 |
| 6052837899185946628 |
| 6341068275337658377 |
| 6341068275337658378 |
+---------------------+
10 rows in set (0.00 sec)
当tidb_enable_clustered_index值为默认值INT_ONLY时,所见的auto_random的表为聚簇表
mysql> select @@global.tidb_enable_clustered_index;
+--------------------------------------+
| @@global.tidb_enable_clustered_index |
+--------------------------------------+
| INT_ONLY |
+--------------------------------------+
1 row in set (0.00 sec)
mysql> show create table t\G
*************************** 1. row ***************************
Table: t
Create Table: CREATE TABLE `t` (
`a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,
PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![auto_rand_base] AUTO_RANDOM_BASE=30001 */
1 row in set (0.00 sec)
AUTO_RANDOM使用限制:
- AUTO_RANDOM列类型必须是BIGINT类型;
- 非聚簇表不支持AUTO_RANDOM;
- 不支持用ALTER TABLE 修改AUTO_RANDOM属性,包括添加或者移除该属性;
- 不支持修改AUTO_RANDOM属性的主键的列类型
- 不支持和AUTO_INCREMENT同时指定在一列上;
- 不支持和列的DEFAULT指定在一列上
- INSERT的时候不支持显示指定AUTO_RANDOM的值,这可能导致提前耗尽用于自动分配的数值