当前位置: 首页 > news >正文

MyCAT分库分表

MyCAT分库分表

前言:

很难评价的软件 尝试通过修改配置文件做到分库分表 你会发现一些很离谱的BUG 或者是主从分离的时候 你也会发现 莫名其妙的BUG

创建基础环境

192.168.3.145192.168.3.159192.168.3.163
MyCAT MySQLMySQLMySQL
--更改root密码alter user 'root'@'localhost' identified by '123';--创建远程登录用户
create user 'root'@'%' identified by '123';--给予权限
grant all on *.* to 'root'@'%';

配置MyCAT数据源

mysql -u root -p123456 -h 127.0.0.1 -P8066-- 添加c1数据源
/*+ mycat:createDataSource
{ "name":"dw0","password":"123","url":"jdbc:mysql://192.168.3.159:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8", "user":"root",}
*/;-- 添加c2数据源
/*+ mycat:createDataSource
{ "name":"dw1","password":"123","url":"jdbc:mysql://192.168.3.163:3306?useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8", "user":"root",}
*/;
#PS: 不知道为什么 通过修改配置文件是行不通的 BUG会很多
#PS:保证远程登录用户的存在与密码正确
/*+ mycat:showDataSources{} */\G; 
查看数据源/*+ mycat:showDataSources() */;
生成配置文件#vim查看
{"dbType":"mysql","idleTimeout":60000,"initSqls":[],"initSqlsGetConnection":true,"instanceType":"READ","maxCon":1000,"maxConnectTimeout":3000,"maxRetryCount":5,"minCon":1,"name":"c1","password":"123","queryTimeout":0,"type":"JDBC","url":"jdbc:mysql://192.168.3.159:3306?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true","user":"root","weight":0
}

PS :查询

mysql> /*+ mycat:showDataSources{} */\G;
*************************** 1. row ***************************NAME: c2USERNAME: rootPASSWORD: 123MAX_CON: 1000MIN_CON: 1EXIST_CON: 0USE_CON: 0MAX_RETRY_COUNT: 5MAX_CONNECT_TIMEOUT: 3000DB_TYPE: mysqlURL: jdbc:mysql://192.168.3.163:3306?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&autoReconnect=trueWEIGHT: 0INIT_SQL: 
INIT_SQL_GET_CONNECTION: trueINSTANCE_TYPE: READIDLE_TIMEOUT: 60000DRIVER: {CreateTime:"2025-08-20 16:05:21",ActiveCount:0,PoolingCount:1,CreateCount:3,DestroyCount:0,CloseCount:5,ConnectCount:7,Connections:[{ID:891191742, ConnectTime:"2025-08-20 16:09:30", UseCount:1, LastActiveTime:"2025-08-20 16:09:30", LastKeepTimeMillis:"2025-08-20 16:14:21"}]
}TYPE: JDBCIS_MYSQL: true
*************************** 2. row ***************************NAME: prototypeDsUSERNAME: rootPASSWORD: 123MAX_CON: 1000MIN_CON: 1EXIST_CON: 0USE_CON: 0MAX_RETRY_COUNT: 5MAX_CONNECT_TIMEOUT: 3000DB_TYPE: mysqlURL: jdbc:mysql://localhost:3306/mysql?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&autoReconnect=trueWEIGHT: 0INIT_SQL: 
INIT_SQL_GET_CONNECTION: trueINSTANCE_TYPE: READ_WRITEIDLE_TIMEOUT: 60000DRIVER: {CreateTime:"2025-08-20 16:05:21",ActiveCount:0,PoolingCount:2,CreateCount:2,DestroyCount:0,CloseCount:43,ConnectCount:43,Connections:[{ID:1553207331, ConnectTime:"2025-08-20 16:05:23", UseCount:31, LastActiveTime:"2025-08-20 16:06:00", LastKeepTimeMillis:"2025-08-20 16:14:21"},{ID:1199305953, ConnectTime:"2025-08-20 16:05:22", UseCount:12, LastActiveTime:"2025-08-20 16:05:23", LastKeepTimeMillis:"2025-08-20 16:14:21"}]
}TYPE: JDBCIS_MYSQL: true
*************************** 3. row ***************************NAME: c1USERNAME: rootPASSWORD: 123MAX_CON: 1000MIN_CON: 1EXIST_CON: 0USE_CON: 0MAX_RETRY_COUNT: 5MAX_CONNECT_TIMEOUT: 3000DB_TYPE: mysqlURL: jdbc:mysql://192.168.3.159:3306?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&autoReconnect=trueWEIGHT: 0INIT_SQL: 
INIT_SQL_GET_CONNECTION: trueINSTANCE_TYPE: READIDLE_TIMEOUT: 60000DRIVER: {CreateTime:"2025-08-20 16:05:21",ActiveCount:0,PoolingCount:1,CreateCount:3,DestroyCount:0,CloseCount:5,ConnectCount:7,Connections:[{ID:1123414141, ConnectTime:"2025-08-20 16:09:30", UseCount:1, LastActiveTime:"2025-08-20 16:09:30", LastKeepTimeMillis:"2025-08-20 16:14:21"}]
}TYPE: JDBCIS_MYSQL: true
3 rows in set (0.01 sec)ERROR: 
No query specified--PS:他可能没有配置文件 查询到就好了

配置集群

#/*+ mycat:createCluster{ "name":"c0", "masters":[  "dw0" ], "replicas":[  "dr0" ]} */;
#--name : 自定义名称 唯一性
#--masters:主库 数据源相同
#--replices:从库 数据源相同/*! mycat:createCluster{ "name":"c0", "masters":[  "dw0" ]} */;/*! mycat:createCluster{ "name":"c1", "masters":[  "dw1" ]} */;# 查看集群
/*+ mycat:showClusters{} */;# 查看集群
/*! mycat:showClusters{} */\G;

创建逻辑库

CREATE DATABASE db1 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;vim /usr/local/mycat/conf/schemas/db1.schema.json
## 在里面添加集群的名称,作用是让该集群生成并管理这个库的物理库
"targetName":"prototype"

创建表

use db1;CREATE TABLE `sys_dict` ( `id` bigint NOT NULL AUTO_INCREMENT,`dict_type` int ,`dict_name` varchar(100) DEFAULT NULL,`dict_value` int , PRIMARY KEY (`id`)) ENGINE=InnoDBDEFAULT CHARSET=utf8mb4BROADCAST;
--上面的SQL中有一个BROADCAST 这个就是全局表的标识。INSERT INTO sys_dict(dict_type,dict_name,dict_value) VALUES(1,"男",1);
INSERT INTO sys_dict(dict_type,dict_name,dict_value) VALUES(1,"女",0);# 所有的库中都有的数据select * from sys_dict;
+----+-----------+-----------+------------+
| id | dict_type | dict_name | dict_value |
+----+-----------+-----------+------------+
|  1 |         1 ||          1 |
|  2 |         1 ||          0 |
+----+-----------+-----------+------------+
2 rows in set (0.00 sec)

创建表

这个命令在主库1里创出来的库名叫db1_0 主库2:db1_1 主库1里的表orders_0 主库2: orders_1

相当于主1和主2加起来是完整的,从1和从2是对应主的备份。

CREATE TABLE orders(  ID BIGINT NOT NULL AUTO_INCREMENT,ORDER_TYPE INT,  CUSTOMER_ID INT,AMOUNT DECIMAL(10,2),  PRIMARY KEY(ID)) ENGINE=INNODB  DEFAULT CHARSET=utf8mb4 dbpartition BY mod_hash(CUSTOMER_ID) tbpartition By mod_hash(CUSTOMER_ID) tbpartitions 1 dbpartitions 2;# dbpartition BY mod_hash(CUSTOMER_ID): 指定数据库的分片算法及使用哪一条数据进行分片
# tbpartition BY mod_hash(CUSTOMER_ID) :指定表的分片算法及使用哪一条数据进行分片
# tbpartitions 1  表的分片数量
# dbpartitions 2  数据库的分片数量

MyCat 分库分表配置(核心)

以下是 MyCat 扩展的分库分表规则,用于将数据分散存储到多个数据库 / 表中:

  • dbpartition BY mod_hash(CUSTOMER_ID)

    • 含义:指定分库规则,使用mod_hash(哈希取模)算法,以CUSTOMER_ID(客户 ID)作为分片键。
    • 作用:根据客户 ID 的哈希值对数据库数量取模,决定这条订单数据存储到哪个物理数据库中。
  • dbpartitions 2

    • 含义:指定分库数量为 2,即订单数据会被分散到 2 个不同的物理数据库中。
    • 配合上一条规则:CUSTOMER_ID哈希取模后结果只能是 0 或 1,分别对应第 1 个和第 2 个数据库。
  • tbpartition BY mod_hash(CUSTOMER_ID)

    • 含义:指定分表规则,同样使用mod_hash算法,以CUSTOMER_ID作为分片键。
    • 作用:在确定了目标数据库后,再根据客户 ID 的哈希值对表数量取模,决定存储到该数据库中的哪个分表。
  • tbpartitions 1

    • 含义:指定每个数据库中的分表数量为 1
    • 配合上一条规则:由于数量为 1,取模结果只能是 0,因此每个数据库中只会有 1 张orders表(不分表,仅分库)。

插入数据

添加数据
INSERT INTO ORDERS(ID,ORDER_TYPE,CUSTOMER_ID,AMOUNT) VALUES(1,101,100,100101);
INSERT INTO ORDERS(ID,ORDER_TYPE,CUSTOMER_ID,AMOUNT) VALUES(2,101,100,100101);
INSERT INTO ORDERS(ID,ORDER_TYPE,CUSTOMER_ID,AMOUNT) VALUES(3,101,100,100101);
INSERT INTO ORDERS(ID,ORDER_TYPE,CUSTOMER_ID,AMOUNT) VALUES(4,102,101,101102);
INSERT INTO ORDERS(ID,ORDER_TYPE,CUSTOMER_ID,AMOUNT) VALUES(5,102,101,101102);
INSERT INTO ORDERS(ID,ORDER_TYPE,CUSTOMER_ID,AMOUNT) VALUES(6,102,101,101102);

结果

数据会被分成两部分 存储在不同的库

表配置

定义:ER 表是与主表存在强关联关系(如父子关系)的表,跟随主表的分片规则存储,确保关联数据在同一分库。
特点

  • 依赖主表的分片键(如主表按 user_id 分片,ER 表也按 user_id 分片)。
  • 主表和 ER 表的数据一定在同一个分库,避免跨库关联。
CREATE TABLE orders_detail( id BIGINT AUTO_INCREMENT,detail VARCHAR(2000),order_id BIGINT, PRIMARY KEY(ID)) ENGINE=INNODB  DEFAULT CHARSET=utf8mb4 dbpartition BY mod_hash(order_id) tbpartition By mod_hash(order_id) tbpartitions 1 dbpartitions 2;#  dbpartition BY mod_hash(order_id) :指定数据库的分片算法及使用哪一条数据进行分片HASHtbpartition
#  BY mod_hash(order_id) :指定表的分片算法及使用哪一条数据进行分片
#  HASHtbpartitions 1  表的分片数量
#  dbpartitions 2     数据库的分片数量

以下是 MyCat 扩展的分库分表规则,用于将订单详情数据与对应的订单数据存储在同一分片(便于关联查询):

  • dbpartition BY mod_hash(order_id)

    • 含义:指定分库规则,使用mod_hash(哈希取模)算法,以order_id(订单 ID)作为分片键。
    • 作用:根据订单 ID 的哈希值对数据库数量取模,决定这条详情数据存储到哪个物理数据库中。
  • dbpartitions 2

    • 含义:指定分库数量为 2,即详情数据会被分散到 2 个物理数据库中(与orders表的分库数量保持一致)。
  • tbpartition BY mod_hash(order_id)

    • 含义:指定分表规则,使用mod_hash算法,以order_id作为分片键。
    • 作用:在确定目标数据库后,根据订单 ID 的哈希值对表数量取模,决定存储到该数据库中的哪个分表。
  • tbpartitions 1

    • 含义:指定每个数据库中的分表数量为 1(即每个数据库中只有 1 张orders_detail表)。

3. 设计意图与效果

这条配置的核心是让订单详情与对应的订单存储在同一个分片,具体效果:

  1. 当插入一条订单详情时,MyCat 会根据order_id的哈希值计算分片位置(与orders表中对应订单的分片位置完全一致);
  2. 最终,同一订单的主表数据(orders)和详情数据(orders_detail)会存储在同一个数据库中;
  3. 这种设计能避免跨库关联查询,提高ordersorders_detail表关联查询的效率。

添加数据

添加数据
INSERT INTO orders_detail VALUES(1,"详情1",1);
INSERT INTO orders_detail VALUES(2,"详情2",2);
INSERT INTO orders_detail VALUES(3,"详情3",3);
INSERT INTO orders_detail VALUES(4,"详情4",4);
INSERT INTO orders_detail VALUES(5,"详情5",5);
INSERT INTO orders_detail VALUES(6,"详情6",6);

结果

以单数和双数分表

分库分表参数的核心用法

  1. dbpartition BY 算法(分片键)

    • 作用:指定分库规则,即 “按什么字段”“用什么算法” 将数据分到不同数据库。
    • 你的配置:dbpartition BY mod_hash(CUSTOMER_ID)
      → 用mod_hash(哈希取模)算法,以CUSTOMER_ID(客户 ID)为依据分库。
  2. dbpartitions N

    • 作用:指定分库的总数量(N 为数字)。
    • 你的配置:dbpartitions 2
      → 数据会被分散到 2 个物理数据库中。
      → 计算逻辑:CUSTOMER_ID的哈希值 % 2 → 结果 0 或 1,对应 2 个数据库。
  3. tbpartition BY 算法(分片键)

    • 作用:指定分表规则,即 “按什么字段”“用什么算法” 在单个数据库内分表。
    • 你的配置:tbpartition BY mod_hash(CUSTOMER_ID)
      → 同样用mod_hash算法,以CUSTOMER_ID为依据分表。
  4. tbpartitions M

    • 作用:指定每个数据库内的分表数量(M 为数字)。
    • 你的配置:tbpartitions 1
      → 每个数据库中只创建 1 张表(即不分表,仅分库)。

除了mod_hash(哈希取模),MyCat 还支持多种分片算法,适用于不同业务场景:

范围分片(range
  • 语法:dbpartition BY range(分片键) + dbpartitions N

  • 原理:按分片键的数值范围分片(如按 ID 区间、时间范围)。

  • 示例:

    -- 按订单ID范围分库:ID≤100000存库1,ID>100000存库2
    CREATE TABLE orders(...)  -- 表结构定义(省略,包含ID等字段)
    -- 分库规则配置
    dbpartition BY range(ID)  -- 按ID字段的范围进行分库
    dbpartitions 2           -- 分库总数量为2个
    -- 具体的范围划分规则
    partition by range(ID) (partition p0 values less than (100000),  -- 规则1:ID < 100000的记录partition p1 values less than maxvalue   -- 规则2:ID ≥ 100000的记录
    );
    --p0 和 p1 是给 “范围规则” 起的名字,方便 MyCat 识别不同的分片逻辑(比如后续修改、删除某条范围规则时,通过名字定位);可自定义
2. 枚举分片(enum
  • 语法:dbpartition BY enum(分片键)

  • 原理:按分片键的枚举值指定分片(如按地区、状态)。

  • 示例:
    sql

    -- 按订单类型分库:TYPE=101存库1,TYPE=102存库2
    CREATE TABLE orders(...)
    dbpartition BY enum(ORDER_TYPE) --按照分片分库
    dbpartitions 2 
    partition by enum(ORDER_TYPE) (partition p0 values in (101), --ORDER_TYPE=101的为一个库partition p1 values in (102)	--ORDER_TYPE=102的为一个库
    );
    
  • 适用场景:分片键值是固定枚举(如性别、支付方式)。

3. 时间分片(date
  • 语法:dbpartition BY date(分片键, 格式)

  • 原理:按时间字段的年 / 月 / 日分片(如按订单创建时间)。

  • 示例:
    sql

    -- 按创建时间(CREATE_TIME)的月份分表,每月1张表
    CREATE TABLE orders(ID BIGINT NOT NULL AUTO_INCREMENT,ORDER_TYPE INT,CUSTOMER_ID INT,AMOUNT DECIMAL(10,2),CREATE_TIME DATETIME,  -- 新增:订单创建时间(分表的依据字段)PRIMARY KEY(ID)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8mb4
    -- 分表规则:按CREATE_TIME的"年月"格式分片
    tbpartition BY date(CREATE_TIME, 'yyyyMM')  
    -- 分表数量:12张(对应1-12月)
    tbpartitions 12;
    
  • 适用场景:日志、订单等时间相关数据(便于按时间范围查询)。

  • MyCat 会自动创建 12 张分表,命名格式为表名_分片索引,例如:

    • orders_0(存储 1 月数据,对应202301202401等所有 1 月数据)
    • orders_1(存储 2 月数据)
    • ...
    • orders_11(存储 12 月数据)
4. 一致性哈希分片(consistent_hash
  • 语法:dbpartition BY consistent_hash(分片键)

  • 原理:基于一致性哈希算法,解决mod_hash在分片数量变化时数据迁移量大的问题。

  • 示例:
    sql

    -- 按客户ID的一致性哈希分库,减少扩缩容时的数据迁移
    CREATE TABLE orders(...) 
    dbpartition BY consistent_hash(CUSTOMER_ID) 
    dbpartitions 3; -- 3个数据库节点
    

  • 适用场景:需要动态扩缩容的集群(如业务增长快,可能增加数据库节点)。

5. 复合分片(多字段组合)
  • 语法:dbpartition BY complex(分片键1, 分片键2)

  • 原理:结合多个字段的分片结果,更灵活地分配数据。

  • 示例:
    sql

    -- 先按客户ID分库,再按订单类型分表
    CREATE TABLE orders(...) 
    dbpartition BY mod_hash(CUSTOMER_ID) dbpartitions 2
    tbpartition BY mod_hash(ORDER_TYPE) tbpartitions 3;--举例
    --SQL 配置的是 **“先分库、后分表” 的复合分片策略 **,即数据先按CUSTOMER_ID分到不同数据库,再在每个数据库内按ORDER_TYPE分到不同表中
    CREATE TABLE book_1 (ID BIGINT NOT NULL,  -- 书籍ID(分库依据)name VARCHAR(100) NOT NULL,  -- 书籍名称take_count INT NOT NULL,  -- 取书数量(分表依据)PRIMARY KEY (ID)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8mb4
    -- 第一步:按ID哈希分库(4个库)
    dbpartition BY mod_hash(ID) 
    dbpartitions 4
    -- 第二步:在每个库内按取书数量范围分表
    tbpartition BY range(take_count)
    tbpartitions 3  -- 每个库分3张表
    (partition small_take values less than (10),  -- 取书数量 <10partition medium_take values less than (50), -- 10≤数量 <50partition large_take values less than maxvalue  -- 数量 ≥50
    );

http://www.dtcms.com/a/340272.html

相关文章:

  • Go特有的安全漏洞及渗透测试利用方法(通俗易懂)
  • 次短路P2865 [USACO06NOV] Roadblocks G题解
  • SLAM文献之-Globally Consistent and Tightly Coupled 3D LiDAR Inertial Mapping
  • RESP协议
  • React响应式链路
  • SCAU学习笔记 - 自科三面前端方向实战演示
  • 157-基于Python的懂车帝汽车数据爬虫分析与可视化系统
  • NVIDIA Isaac Sim
  • Ubuntu 主机名:精通配置与管理
  • 全球首款 8K 全景无人机影翎 A1 发布解读:航拍进入“先飞行后取景”时代
  • 从 “模仿” 到 “创造”:AI 大模型的 “思维进化” 背后,技术突破在哪?
  • 沪深股指期货指数「IF000」期货行情怎么看?
  • 利用无事务方式插入数据库解决并发插入问题(最小主键id思路)
  • 海外短剧app、h5、独立站、国内短剧看广告app,短剧小程序、源码交付开发
  • java17学习笔记
  • RK android14 Setting一级菜单IR遥控器无法聚焦问题解决方法
  • VPS海外节点性能监控全攻略:从基础配置到高级优化
  • 02-docker相关知识
  • Java 学习笔记(基础篇6)
  • 29.Linux rsync+inotify解决同步数据实时性
  • 【Tech Arch】Apache HBase分布式 NoSQL 数据库
  • 签名应用APP分发平台的微服务化部署是什么?其有哪些优势?
  • 微服务自动注册到ShenYu网关配置详解
  • mysql数据恢复
  • WT2606B 驱屏语音芯片新增蓝牙功能:功能集成一体化,产品升级自动化,语音交互无线化,场景应用普适化!
  • Java 性能优化实战(二):JVM 调优的 5 个核心维度
  • 2.Shell脚本修炼手册之---创建第一个 Shell 脚本
  • Windows 11 安装 Miniconda + Mamba,配置国内源
  • KV cache
  • java八股文-JVM相关面试题-参考回答