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.mfbz.cn/a/2813.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++开发/Qt开发:单例模式介绍与应用

单例模式是软件设计模式中最简单也是最常用的一种创建型设计模式。它的核心目标是确保一个类在整个应用程序生命周期中只有一个实例&#xff0c;并提供一个全局访问点。笔者白话版理解&#xff1a;你创建了一个类&#xff0c;如果你希望这个类对象在工程中应用时只创建一次&…

学习设计模式《二十三》——桥接模式

一、基础概念 桥接模式的本质是【分离抽象和实现】。 桥接模式的定义&#xff1a;将抽象部分与它的实现部分分离&#xff0c;使它们都可以独立地变化。 认识桥接模式序号认识桥接模式说明1什么是桥接通俗点说就是在不同的东西之间搭一个桥&#xff0c;让它们能够连接起来&a…

HTML+CSS:浮动详解

在HTMLCSS布局中&#xff0c;浮动&#xff08;float&#xff09; 是一种经典的布局技术&#xff0c;用于控制元素在页面中的排列方式。它最初设计用于实现文字环绕图片的效果&#xff0c;后来被广泛用于复杂布局&#xff0c;但随着Flexbox和Grid的兴起&#xff0c;其使用场景有…

PAT 1074 Reversing Linked List

题目的意思给出一个链表&#xff0c;让我们每隔K个进行一次反转&#xff0c;如果不足K个的&#xff0c;就不进行。 对于链表反转的题目&#xff0c;我第一时间想出来的是&#xff0c;原地进行逆置&#xff0c;不断的变化指针&#xff0c;但这样很麻烦&#xff0c;没有想出来&am…

python学习DAY46打卡

DAY 46 通道注意力(SE注意力) 内容&#xff1a; 不同CNN层的特征图&#xff1a;不同通道的特征图什么是注意力&#xff1a;注意力家族&#xff0c;类似于动物园&#xff0c;都是不同的模块&#xff0c;好不好试了才知道。通道注意力&#xff1a;模型的定义和插入的位置通道注意…

猫头虎AI分享|字节开源了一款具备长期记忆能力的多模态智能体:M3-Agent 下载、安装、配置、部署教程

猫头虎AI分享&#xff5c;字节开源了一款具备长期记忆能力的多模态智能体&#xff1a;M3-Agent 大家好&#xff0c;我是猫头虎 &#x1f989;&#x1f42f;&#xff0c;今天给大家带来一个超硬核的开源 AI 项目分享&#xff1a;M3-Agent。这是一款由字节开源的、多模态智能体框…

应用缓存不止是Redis!——亿级流量系统架构设计系列

在当今互联网架构中&#xff0c;缓存技术犹如系统的"加速器"&#xff0c;通过将热点数据存储在高速介质中&#xff0c;显著降低数据库负载并提升响应速度。无论是CPU的L1/L2/L3缓存&#xff0c;还是分布式系统中的Redis集群&#xff0c;缓存无处不在。本文将深入探讨…

洛谷 P2834 纸币问题 3-普及-

题目背景 你是一个非常有钱的小朋友。 注意&#xff1a; 本题和《进阶篇》的对应题目&#xff0c;输入格式略有差异。 题目描述 你有 nnn 种面额互不相同的纸币&#xff0c;第 iii 种纸币的面额为 aia_iai​ 并且有无限张&#xff0c;现在你需要支付 www 的金额&#xff0c;请问…

C++常见面试题-5.数据结构

五、数据结构 5.1 线性数据结构数组和链表的区别&#xff1f;数组&#xff08;Array&#xff09;&#xff1a; 存储方式&#xff1a;连续的内存空间&#xff1b;访问方式&#xff1a;支持随机访问&#xff0c;通过索引直接访问元素&#xff0c;时间复杂度为O(1)&#xff1b;插入…

Node.js 在 Windows Server 上的离线部署方案

Node.js 在 Windows Server 上的离线部署方案 离线部署的核心是提前准备所有依赖资源&#xff08;避免在线下载&#xff09;&#xff0c;并通过本地配置完成服务搭建&#xff0c;整体分为「依赖准备」「环境配置」「项目部署」「服务注册」4个阶段。 一、提前准备离线资源&am…

18.web api 9

3.M端事件4.js插件

母猪姿态转换行为识别:计算机视觉与行为识别模型调优指南

> 在现代智能化养殖中,母猪姿态识别是健康监测的关键技术。本文将带你从0到1构建高精度母猪姿态识别系统,准确率可达95%以上! ## 一、为什么母猪姿态识别如此重要? 母猪的行为姿态是其健康状况的重要指标: - **站立姿态**:可能表示发情期或进食需求 - **侧卧姿态**:…