背景信息
什么是隐式序列
在传统的单库环境中,AUTO_INCREMENT是用于生成主键自增值的常用机制,能够保证主键在单实例数据库中的唯一性。然而,在分布式数据库DRDS中,数据被分片存储在多个存储节点中,原有的自增机制将无法保证全局唯一性,因此DRDS引入了基于全局序列的隐式序列机制,用于替代传统的AUTO_INCREMENT功能。
隐式序列与AUTO_INCREMENT的关系
在DRDS中,虽然通过添加AUTO_INCREMENT关键字实现自增,但实际不是调用数据库原生的自增逻辑,而是通过隐式的全局序列实现唯一值生成。
注意
隐式序列由系统自动维护,无需用户手动干预。
隐式序列的生命周期
隐式序列由系统在建表时自动创建,并在DROP表时自动删除。
注意
不推荐用户手动创建或删除隐式序列,可能会造成ID冲突或数据一致性问题。
HINT路由下的行为差异
当使用HINT路由 + INSERT语句
时,DBProxy无法改写SQL,因此不会自动填充自增ID:
注意
不推荐在需要使用AUTO_INCREMENT功能的表中使用HINT路由。
以/*+TDDL:node('group1')*/ INSERT INTO test(value) VALUES(1);
为例,该命令将直接透传到物理库。若该表中的自增列未显式给值,数据库可能会使用默认值(例如0),若该值不唯一,则会报错(例如Duplicate entry
)。
使用限制
只有版本≥ 2.3.1的DBProxy实例支持隐式序列功能。
隐式序列必须为非循环序列:
循环序列无法满足AUTO_INCREMENT递增且唯一的要求。因此,DRDS创建的隐式序列默认为非循环序列,且不支持修改为循环序列。
隐式序列必须唯一绑定一个表使用:
隐式序列与表应一对一绑定,不能被多个表共用。
禁止手动在其他表中使用已存在的隐式序列。
语法说明
在DRDS中使用隐式序列功能,只需要在创建表时添加auto_increment
关键字即可实现,实现过程如下:
创建表的时候添加
auto_increment
语法,声明某一列为自增主键。语法示例如下:
CREATE TABLE `test` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `value` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) AUTO_INCREMENT=1000;
系统开始创建分片表,并自动创建一个隐式全局序列。
DRDS将自动为表中的
AUTO_INCREMENT
字段创建一个隐式全局序列,命名为AUTO_SEQ_<TableName>
,例如AUTO_SEQ_test
。初始值
AUTO_INCREMENT=1000
将作为该全局序列的起始值,默认每次自增1,即生成的序列为:1000,1001,1002...说明
默认起始值为1。
向分片表写入数据的过程中,DBProxy自动将SQL语句改写为自带隐式全局序列的形式,保证自增序列全局唯一。
SQL改写示例如下:
-- 原始SQL INSERT INTO test(value) VALUES(1); -- 改写后SQL(在DBProxy层完成) INSERT INTO test(id, value) VALUES(auto_seq_test.nextval, 1);
该示例表示,在执行
INSERT
命令插入数据时,DRDS的中间件层(DBProxy)会自动将SQL语句改写为显式带入序列值的形式(改写后的SQL语句自动添加了auto_seq_test.nextval
关键字),执行该命令时,系统会自动按照当前的隐式全局序列AUTO_SEQ_test
排序情况继续排序。