当使用 Mycat 作为一个分库分表的逻辑数据库时,序列是为逻辑表自增字段提供自增功能的对象。其概念类似于 Oracle 、DB2 、MS SQL 等传统数据库中序列的概念。
Mycat 2 官方将分序列为 Mycat 2 生成的(全局)序列和由 MySQL 生成的序列两种。
但笔者在查阅源码时发现 TimeBasedSequence
,这个也是使用的雪花算法,似乎就只是 Mycat 序列注释里的 Time
属性,也并没有完全实现,与默认的 Mycat 2 序列所采用的雪花算法没有区别。
笔者理解,Mycat 2 目前版本其实序列只有一种,即 Mycat 2 生成的序列,也就是全局序列。
而 MySQL 生成的序列,虽然有对应的 clazz
属性设置,可似乎没有实现。并且,笔者认为,既然交由 MySQL 管理自增字段,就不需要 Mycat 对序列做什么了,而是由数据库解决方案设计者自行设计、管理,Mycat 仅负责查询汇总。
而且 Mycat 2 倘若后续实现了该功能,笔者认为也是得不偿失的,因为实现该功能的复杂性远大于其价值,成本过高。
如果想实现将如下 SQL 语句自动将数据分布在不同存储节点上,要么很难,要么有诸多使用限制。
insert into db_not_tb__city(name,city) values('a','sh'),('b','sh'),('c','bj'),('d','sh'),('e','sz'),('f','bj'),('g','bj'),('h','sz');
一种比较好的设计是添加新的注释功能或者 SQL 方言(这个 Mycat 团队应该没能力实现),指定插入数据的存储位置。例如,将如上语句分为两个 INSERT
语句。
insert /*+ mycat:"locality":{"targetName":"cls0" }*/ into db_not_tb__city(name,city) values('a','sh'),('b','sh'),('c','bj'),('d','sh');
insert /*+ mycat:"locality":{"targetName":"cls1" }*/ into db_not_tb__city(name,city) values('e','sz'),('f','bj'),('g','bj'),('h','sz');
前文已经提过,Mycat 2 实际实现的只有 Mycat 2 利用默认的雪花算法生成的全局序列,因而本文不打算介绍 MySQL 生成序列。
需要在 Mycat 2 原型库或默认存储节点使用 mysql 客户端执行 dbseq.sql
(本文绑定资源点击下载) 脚本,创建 Mycat 全局序列表 mycat_sequence
和相应的序列函数。注意,此步骤只需执行一次。
在使用序列时,如果需要显示指定 targetName
属性,应与执行 dbseq.sql
的数据库相对应。
序列的命名规范是 物理库名
+ _
+ 物理表名
,对应的物理存储的序列配置文件名称为 物理库名
+ _
+ 物理表名
+ .sequence.json
。
**注意,不要使用纯英文字幕和数字组成的表名,当前 Mycat 有 Bug 无法识别。**详见 Mycat 2 无法识别普通表名 。
例如,sharding_db_not_tb
这个序列名中,sharding
表示物理库 sharding
,do_not_tb
表示物理库 sharding
中的物理表 do_not_tb
。
注意
尽管 Mycat 支持逻辑库、表与物理库、表名称不同,但笔者强烈建议设计为相同,以避免不这么做带来的复杂性和不确定性。
依旧使用上面的例子,假设您要创建的序列名称为 sharding_db_not_tb
,则需要向全局序列表中添加对应的一条数据记录。注意,初始值咬设置为 0 。
insert into mycat_sequence values('sharding_db_not_tb',0,1);
Mycat 默认即采用雪花算法创建全局序列。
/*+ mycat:setSequence{"name":"sharding_db_not_tb"} */;
# 或者加 `time` 属性
/*+ mycat:setSequence{"name":"sharding_db_not_tb","time":true} */;
AUTO_INCREMENT
在表字段后使用 AUTO_INCREMENT
子句(或属性)。
例如:
# create table
/*+ mycat:createTable{
"schemaName":"sharding",
"shardingTable":{
"createTableSQL":"create table db_not_tb(id int primary key AUTO_INCREMENT,name varchar(10),city varchar(10)) dbpartition by MOD_HASH(id) dbpartitions 2",
"function":{
"properties":{
"dbNum":2,
"dbMethod":"mod_hash(id)",
"mappingFormat":"cls${targetIndex}/sharding/db_not_tb",
"storeNum":2
}
}
},
"tableName":"db_not_tb"
} */;
Mycat 全局序列的核心要点其实是:
dbseq.sql
在原型库所创建全局序列表及相关函数。AUTO_INCREMENT