Jw
首页
技术
英语
首页
技术
英语
  • MySQL

    • MySQL 基础
    • 环境变量配置(PATH)
    • SQL 语法与分类
    • MySQL 数据类型
    • SQL - DDL 数据定义语言
    • SQL - DML 数据操作语言
    • SQL - DQL 数据查询语言
    • SQL - DCL 数据控制语言
    • MySQL 函数
    • SQL 约束
    • SQL 外键约束
    • 多表关系
    • 多表查询(连接查询)
    • 隐式内连接 vs 显式内连接
    • 子查询
    • 多表查询案例
    • 事务
    • 并发事务问题与隔离级别
    • MySQL 体系结构与存储引擎
    • 索引概述
    • 索引结构
    • 索引分类
    • 索引语法
    • SQL 性能分析
    • 索引使用
    • 索引设计原则
    • SQL 优化 - 插入数据与主键优化
    • SQL 优化 - order by 与 group by
    • SQL 优化 - limit / count / update
    • 视图
    • 存储过程
    • 存储过程 - 变量
    • 存储过程 - 流程控制、游标与条件处理
    • 存储函数
    • 触发器
    • 锁概述与全局锁
    • 表级锁
    • 行级锁
    • InnoDB 逻辑存储结构
    • InnoDB 架构
    • 事务原理(redo / undo log)
    • MVCC
    • MySQL 系统数据库
    • MySQL 常用工具
    • 数据备份与导入导出
    • 错误日志与二进制日志
    • 查询日志与慢查询日志
    • 主从复制 - 概述与原理
    • 主从复制 - 搭建
    • Mycat 配置
    • Mycat 垂直拆分与水平拆分
    • Mycat 分片规则
    • Mycat 管理与监控
    • Mycat 读写分离 - 一主一从
    • Mycat 读写分离 - 双主双从

Mycat 垂直拆分与水平拆分

垂直拆分按业务把不同的表放到不同库;水平拆分把同一张表的数据按规则分散到多个库。Mycat 通过 schema.xml 把逻辑表映射到多个 dataNode。

一、垂直拆分

1.1 场景

业务系统中,用户与订单每天都会产生大量数据,单台服务器的数据存储及处理能力是有限的,可以对数据库表进行拆分。

业务模块表
省市区tb_areas_city、tb_areas_provinces、tb_areas_region
商品tb_goods_base、tb_goods_brand、tb_goods_cat、tb_goods_desc、tb_goods_item
订单tb_order_item、tb_order_master、tb_order_pay_log
用户tb_user、tb_user_address

拆分后:商品相关表 → dataNode1,订单相关表 → dataNode2,省市区 + 用户相关表 → dataNode3。

schema
└── table
    ├── dataNode1(商品)
    ├── dataNode2(订单)
    └── dataNode3(省市区 / 用户)

1.2 准备

角色地址(示例)
Mycat1.2.3.4
MySQL1.2.3.5、1.2.3.6、1.2.3.7

分别在三台 MySQL 中创建数据库 shopping。

1.3 配置 schema.xml

<schema name="SHOPPING" checkSQLschema="true" sqlMaxLimit="100">
    <table name="tb_goods_base"    dataNode="dn1" primaryKey="id"/>
    <table name="tb_goods_brand"   dataNode="dn1" primaryKey="id"/>
    <table name="tb_goods_cat"     dataNode="dn1" primaryKey="id"/>
    <table name="tb_goods_desc"    dataNode="dn1" primaryKey="goods_id"/>
    <table name="tb_goods_item"    dataNode="dn1" primaryKey="id"/>

    <table name="tb_order_item"    dataNode="dn2" primaryKey="id"/>
    <table name="tb_order_master"  dataNode="dn2" primaryKey="order_id"/>
    <table name="tb_order_pay_log" dataNode="dn2" primaryKey="out_trade_no"/>

    <table name="tb_user"          dataNode="dn3" primaryKey="id"/>
    <table name="tb_user_address"  dataNode="dn3" primaryKey="id"/>
    <table name="tb_areas_provinces" dataNode="dn3" primaryKey="id"/>
    <table name="tb_areas_city"      dataNode="dn3" primaryKey="id"/>
    <table name="tb_areas_region"    dataNode="dn3" primaryKey="id"/>
</schema>

<dataNode name="dn1" dataHost="dhost1" database="shopping" />
<dataNode name="dn2" dataHost="dhost2" database="shopping" />
<dataNode name="dn3" dataHost="dhost3" database="shopping" />

同时 server.xml 中该用户的 schemas 要包含 SHOPPING。

primaryKey 用于 Mycat 定位分片,避免全节点扫描;表名大小写要与实际库表一致。

1.4 全局表配置

省、市、区 / 县表 tb_areas_provinces、tb_areas_city、tb_areas_region 属于数据字典表,多个业务模块中都可能会遇到,可以将其设置为全局表,利于业务操作。

<table name="tb_areas_provinces" dataNode="dn1,dn2,dn3" primaryKey="id" type="global"/>
<table name="tb_areas_city"      dataNode="dn1,dn2,dn3" primaryKey="id" type="global"/>
<table name="tb_areas_region"    dataNode="dn1,dn2,dn3" primaryKey="id" type="global"/>

全局表会在每个数据节点上保留一份完整数据,写操作同步到所有节点,适合数据量小、读取频繁的字典表。

二、水平拆分

2.1 场景

业务系统中有一张日志表 tb_log,每天都会产生大量日志数据,单台服务器的存储及处理能力有限,可以对表进行拆分:同一张表按规则分散到多个节点。

schema → table(tb_log)
          ├── dataNode1:tb_log
          ├── dataNode2:tb_log
          └── dataNode3:tb_log

2.2 准备

分别在三台 MySQL 中创建数据库 itcast。

2.3 配置 schema.xml

<schema name="ITCAST" checkSQLschema="true" sqlMaxLimit="100">
    <table name="tb_log" dataNode="dn4,dn5,dn6" rule="mod-long" />
</schema>

<dataNode name="dn4" dataHost="dhost1" database="itcast" />
<dataNode name="dn5" dataHost="dhost2" database="itcast" />
<dataNode name="dn6" dataHost="dhost3" database="itcast" />

server.xml 中用户可访问的逻辑库要加上 ITCAST:

<property name="schemas">SHOPPING,ITCAST</property>

水平拆分必须指定 rule;dataNode 写多个节点,Mycat 按规则路由。

2.4 测试

在 mycat 的命令行中执行如下 SQL 创建表并插入数据,查看数据分布情况:

CREATE TABLE tb_log(
    id bigint(20) NOT NULL COMMENT 'ID',
    model_name varchar(200) DEFAULT NULL COMMENT '模块名',
    model_value varchar(200) DEFAULT NULL COMMENT '模块值',
    return_value varchar(200) DEFAULT NULL COMMENT '返回值',
    return_class varchar(200) DEFAULT NULL COMMENT '返回值类型',
    operate_user varchar(20) DEFAULT NULL COMMENT '操作用户',
    operate_time varchar(20) DEFAULT NULL COMMENT '操作时间',
    param_and_value varchar(500) DEFAULT NULL COMMENT '请求参数名及参数值',
    operate_class varchar(200) DEFAULT NULL COMMENT '操作类',
    operate_method varchar(200) DEFAULT NULL COMMENT '操作方法',
    cost_time bigint(20) DEFAULT NULL COMMENT '执行方法耗时,单位 ms',
    source int(1) DEFAULT NULL COMMENT '来源:1 PC,2 Android,3 IOS',
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

建表会在所有分片节点上执行;插入时按 rule="mod-long" 对 id 取模,数据落到不同节点。

三、垂直拆分 vs 水平拆分

对比项垂直拆分水平拆分
拆分对象不同的表(按业务)同一张表的数据
解决的问题单库表太多、业务耦合单表数据量过大
典型配置dataNode="dn1" 每表一个节点dataNode="dn4,dn5,dn6" + rule
是否需分片规则不需要必须指定 rule

速查

<!-- schema.xml:垂直拆分,按业务把表分到不同节点 -->
<schema name="SHOPPING" checkSQLschema="true" sqlMaxLimit="100">
    <table name="tb_goods_base"   dataNode="dn1" primaryKey="id"/>
    <table name="tb_order_master" dataNode="dn2" primaryKey="order_id"/>
    <table name="tb_user"         dataNode="dn3" primaryKey="id"/>
</schema>

<!-- 全局表:每个节点都存一份(字典表) -->
<table name="tb_areas_city" dataNode="dn1,dn2,dn3" primaryKey="id" type="global"/>

<!-- schema.xml:水平拆分,同一张表按规则分散 -->
<schema name="ITCAST" checkSQLschema="true" sqlMaxLimit="100">
    <table name="tb_log" dataNode="dn4,dn5,dn6" rule="mod-long" />
</schema>

<!-- 节点与物理库的映射 -->
<dataNode name="dn4" dataHost="dhost1" database="itcast" />
要做什么配置
按业务拆表每张表 dataNode="dnX"
字典表每节点一份dataNode="dn1,dn2,dn3" + type="global"
同一张表分片多个 dataNode + rule
让用户能访问新库server.xml 的 schemas 加上逻辑库名

相关

  • Mycat 配置:schema.xml / rule.xml / server.xml
  • Mycat 分片规则:水平拆分用的各种 rule
  • Mycat 管理与监控:查看分片节点与数据分布
最近更新: 2026/10/25 21:59
Contributors: liujw
Prev
Mycat 配置
Next
Mycat 分片规则