文章目录
一、准备工作
1. 数据库架构
1.1 Mycat 配置
- Mycat 服务实例使用默认 Mycat 端口
8066
。 - 逻辑方案, 名称采用
sharding
,对应各存储节点上同名的物理方案。 - 分片算法统一采用
MOD_HASH()
。
注释
Schema,即方案或模式,在 MySQL 中等同于数据库。
集群 | 数据源 | 连接串 |
---|---|---|
cls0 | part0 | jdbc:mysql://source:3308/sharding |
cls0 | part0_rep1 | jdbc:mysql://replica1:3308/sharding |
cls1 | part1 | jdbc:mysql://replica2:3308/sharding |
连接 Mycat ,使用 Mycat 注释功能创建 sharding
逻辑方案。
/*+ mycat:createSchema{
"customTables":{},
"globalTables":{},
"normalTables":{},
"schemaName":"sharding",
"shardingTables":{},
"targetName":"cls02"
} */;
重要
因在 Mycat 2 中使用CREATE TABLE
建表时默认使用的是以c+数字
(c0
起始)为名的集群,故如果集群或数据源名称不是以此种方式命名时,使用该方法建表会报错。因而笔者在本文所有测试均采用注释的方式建表,也可以采用直接编辑配置文件的方式,特此说明。
1.2 MySQL 实例配置
主机名 | 端口 | 实例名 | 架构 | 角色 |
---|---|---|---|---|
source | 3308 | rep01Src | 主从 | 主 |
replica1 | 3308 | rep01Rep01 | 主从 | 从 |
replica2 | 3308 | part2 | 单节点 | 单节点 |
2. 分片粒度
分片粒度从高到低依次为:
- MySQL 实例
- Schema
- 表
日常工作中,由于“数据库”一词不严谨的或广义定义存在多义性,可指代如下概念:
- 安装了数据库的服务器。
- 运行于服务器上的数据库服务器应用程序(软件),比如 MySQL 的 mysqld ,Oracle 的 Oracle Database 、Grid 、Clusterware 等 。
- 运行于服务器上的数据库服务器的实例,表示一组后台进程和内存结构,对外提供数据库服务,比如 Oracle 数据库实例,MySQL 实例。
- 数据库服务器实例对应的物理存储文件和逻辑概念。逻辑概念 “Database” 有时也称为 “Schema” ,一般译为“模式”或“方案”。不同数据库产品中, “Database” 与 “Schema” 的关系也不一样,比如在 Oracle 中一个 “Database” 可包含多个 “Schema”;而 MySQL 中 “Database” 与 “Schema” 完全等价。
因而,笔者觉得有必要加以区分以避免歧义,故将“分库”细分为“分实例”和“分库”:
- 分实例:将数据以实例为粒度分片。
- 分库:将数据以实例下的 Schema 为粒度分片。
简言之,本文中“库”只表示 Schema 。
二、测试
3. 分实例、不分库、不分表
注释
本节由于是最先测试的,后对文章做了一些修正,尤其是定义和目录结构方面,因而测试用例中表命名不规范,其中的db
应替换为inst
。
3.1 数据分片映射关系
逻辑表 | 分片 ID | 分片键 | 物理实例(存储节点) | 物理库 | 物理表 | 描述 |
---|---|---|---|---|---|---|
db_not_tb | 0 | id | rep01Src | sharding | db_not_tb | id 双数 |
db_not_tb | 1 | id | part2 | sharding | db_not_tb | id 单数 |
db_not_tb__city | 0 | city | rep01Src | sharding | db_not_tb__city | city 散列化后双数 |
db_not_tb__city | 1 | city | part2 | sharding | db_not_tb__city | city 散列化单数 |
3.2 测试用例
测试用例 | 用例描述 | 序列类型 | 序列名 | 是否必须配置序列 | 逻辑表 | 分片键 | 物理实例(存储节点) | 物理表 |
---|---|---|---|---|---|---|---|---|
1 | 序列采用默认雪花算法,表名含“_”,分片键为 id | 雪花 | sharding_db_not_tb | 否 | db_not_tb | id | rep01Src | db_not_tb |
2 | 序列采用默认雪花算法,表名不含“_”,分片键为 id | 雪花 | sharding_dbnottb | 否 | dbnottb | id | rep01Src | donottb |
3 | 序列采用由 MySQL 生成方式,表名含“_”,分片键为 id | MySQL | sharding_db_not_tb_m | 是 | db_not_tb_m | id | rep01Src | db_not_tb_m |
4 | 序列采用由 MySQL 生成方式,表名不含“_”,分片键为 id | MySQL | sharding_dbnottbm | 是 | dbnottbm | id | rep01Src | dbnottbm |
5 | 序列采用默认雪花算法,表名含“_”,分片键为 city | 雪花 | sharding_db_not_tb__city | 是 | db_not_tb__city | city | rep01Src | db_not_tb__city |
3.3 测试过程
3.3.1 用例1
测试时实际并没有手动创建sharding_db_not_tb
序列,而是使用 Mycat 的默认行为。
# drop old table, and delete old data record
drop table if exists db_not_tb;
delete from mycat_sequence where name = 'sharding_db_not_tb';
# 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"
} */;
# insert relative sequence record into `mycat_sequence`
insert into mycat_sequence values('sharding_db_not_tb',0,1);
# insert data
insert into db_not_tb(name,city) values('a','sh'),('b','sh'),('c','bj'),('d','sh'),