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

彻底分清:垂直分库、水平分库、垂直分表、水平分表(附 Mycat 完整配置)

Mycat 分库分表配置详解:垂直/水平 分库/分表 一网打尽

Mycat 作为经典的数据库中间件,其核心功能就是对数据进行分片,而分片又常被划分为四种典型策略:垂直分库、水平分库、垂直分表、水平分表。很多人在配置时对rule的写法、分片键的位置、多表规则能否复用等问题感到困惑。本文将用最清晰的配置示例和总结,一次性讲透这四种方式,并给出可直接套用的模板。

本文基于 Mycat 1.6+ 版本,配置均以schema.xmlrule.xml为例。


0. 公共基础结构

在开始之前,先给出 Mycat 的schema.xml基本骨架,后面的所有配置都将基于此展开:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

<!-- 逻辑库 -->
<schema name="MYCAT_DB" checkSQLschema="false" sqlMaxLimit="100">
<!-- 各种 <table> 配置放在这里 -->
</schema>

<!-- 数据节点:逻辑库 → 物理库 -->
<dataNode name="dn1" dataHost="host1" database="db1" />
<dataNode name="dn2" dataHost="host2" database="db2" />
<dataNode name="dn3" dataHost="host3" database="db3" />

<!-- 物理主机配置(示例仅写一个,实际可扩展) -->
<dataHost name="host1" maxCon="1000" minCon="10"
balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="127.0.0.1:3306" user="root" password="123456"/>
</dataHost>
<!-- host2、host3 配置类似,略 -->

</mycat:schema>

rule.xml的基本结构:

<?xml version="1.0"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<!-- 这里放 tableRule 和 function -->
</mycat:rule>

1. 垂直分库(按业务分库,整表迁移)

特点:不同业务表放在不同的数据库节点上,不涉及数据行的拆分,不需要配置分片规则(rule)

场景:用户表、订单表、商品表分别存入不同的物理库。

schema.xml 配置

<schema name="MYCAT_DB" checkSQLschema="false" sqlMaxLimit="100">
<!-- 用户模块:放在 dn1 -->
<table name="t_user" dataNode="dn1" primaryKey="id"/>
<table name="t_user_addr" dataNode="dn1" primaryKey="id"/>

<!-- 订单模块:放在 dn2 -->
<table name="t_order" dataNode="dn2" primaryKey="order_id"/>
<table name="t_order_item" dataNode="dn2" primaryKey="id"/>

<!-- 商品模块:放在 dn3 -->
<table name="t_goods" dataNode="dn3" primaryKey="id"/>
</schema>
  • 每一张表都完整存在于某个库中,Mycat 仅负责将 SQL 路由到对应的数据节点。
  • 无 rule,因为数据没有被打散。

2. 水平分库(一张表的数据散列到多个库)

特点:同一张表的结构在多个库中都有,数据按分片键分散存储,必须配置分片规则(rule)
与水平分表的核心区别:水平分库的 <table> 里是多个dataNode,且没有subTables

为避免和单库分表混淆,这里用两张关联表(订单表、订单项表)同时进行水平分库的示例。

schema.xml

<schema name="MYCAT_DB" checkSQLschema="false" sqlMaxLimit="100">
<!-- 两张表都水平分库到 dn1,dn2,dn3,共用同一个 rule -->
<table name="t_order" dataNode="dn1,dn2,dn3" rule="mod_rule" primaryKey="id"/>
<table name="t_order_item" dataNode="dn1,dn2,dn3" rule="mod_rule" primaryKey="id"/>
</schema>

rule.xml(取模分片)

<tableRule name="mod_rule">
<rule>
<columns>id</columns> <!-- 分片键 -->
<algorithm>mod-long</algorithm>
</rule>
</tableRule>

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<property name="count">3</property> <!-- 分为3个库 -->
</function>

说明

  • 分片键id写在 rule 的<columns>里,物理表中必须包含该字段。
  • 多张表共用mod_rule,Mycat 会根据每张表的分片键独立路由到对应库,完全不需要重复定义 rule。
  • 因为两张表的分片规则一致,关联查询(如JOIN ON id)时,数据大概率落在同一分片节点,避免跨库 JOIN。

3. 垂直分表(单库内大表拆小表:主表 + 扩展表)

特点:在同一个数据库中,将一张表的字段拆分成多张表(如常用字段与大字段分离)。
核心真相:垂直分表是纯人工手动拆表,Mycat 不参与任何字段拆分或合并逻辑,它只负责声明表在哪个节点!

场景:商品表拆分为t_goods_main(高频小字段)和t_goods_ext(大文本字段)。

物理建表(自己在 MySQL 中执行)

-- 主表:常用字段
CREATE TABLE t_goods_main(
id INT PRIMARY KEY,
goods_name VARCHAR(50),
price DECIMAL(10,2),
stock INT
);

-- 扩展表:大字段、冷门字段
CREATE TABLE t_goods_ext(
goods_id INT PRIMARY KEY, -- 与主表 id 一一对应
goods_detail LONGTEXT,
goods_img TEXT
);

schema.xml 配置

<schema name="MYCAT_DB" checkSQLschema="false" sqlMaxLimit="100">
<!-- 两张表都在同一个数据节点 dn1,没有 rule -->
<table name="t_goods_main" dataNode="dn1" primaryKey="id"/>
<table name="t_goods_ext" dataNode="dn1" primaryKey="goods_id"/>
</schema>

Mycat 这段配置只做了三件事

  1. 告诉 Mycat 这两张表都在dn1库中;
  2. 声明各自的主键字段;
  3. 不控制任何字段,字段如何拆分完全由建表时决定。

正因为是“纯手动”,所以垂直分表不需要任何 rule,增删改查也需要自己写关联 SQL(见下文第 7 节)。


4. 水平分表(单库内,逻辑表拆多张物理子表)

特点:在同一个数据库中,一张逻辑表对应多张物理子表(如t_log_0,t_log_1……),数据按分片键自动路由到对应的子表。必须配置 rule

schema.xml

<schema name="MYCAT_DB" checkSQLschema="false" sqlMaxLimit="100">
<!-- 单库 dn1,分成 4 张子表:t_log_0 ~ t_log_3 -->
<table name="t_log" subTables="t_log_$0-3" dataNode="dn1" rule="log_rule" primaryKey="id"/>
</schema>

rule.xml(单库内取模)

<tableRule name="log_rule">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<property name="count">4</property> <!-- 单库分4张表 -->
</function>

注意subTables="t_log_$0-3"表示物理表名称为t_log_0t_log_1t_log_2t_log_3,Mycat 会根据分片算法自动计算目标子表。


5. 组合:水平分库 + 水平分表(常用)

将数据先分到多个库,每个库内再分多张子表。例如订单表分 2 个库,每个库内分 2 张子表,总共 4 个分片。

schema.xml

<table name="t_order" dataNode="dn1,dn2" subTables="t_order_$0-1" rule="order_rule" primaryKey="id"/>

rule.xml

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<property name="count">4</property> <!-- 2库 × 2表 = 4 -->
</function>

6. 多表分片规则:复用与独立性

6.1 同分片规则 → 复用同一个 rule(推荐)

如果多张关联表都按照相同的分片键和算法分片,只需定义一个 rule,多次引用即可。

<!-- schema.xml -->
<table name="t_order" dataNode="dn1,dn2,dn3" rule="mod_rule" primaryKey="id"/>
<table name="t_order_item" dataNode="dn1,dn2,dn3" rule="mod_rule" primaryKey="id"/>

rule.xml中只写一份mod_rule全局复用

6.2 不同表分片规则可以不一致(允许)

对于毫无关联的业务表,可以使用完全不同的分片键和分片算法。

<!-- schema.xml -->
<table name="t_order" dataNode="dn1,dn2,dn3" rule="mod_rule" primaryKey="order_id"/>
<table name="t_pay" dataNode="dn1,dn2,dn3" rule="range_rule" primaryKey="user_id"/>

rule.xml定义两套独立的规则:

<!-- 规则1:取模 -->
<tableRule name="mod_rule">
<rule>
<columns>order_id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>

<!-- 规则2:范围分片 -->
<tableRule name="range_rule">
<rule>
<columns>user_id</columns>
<algorithm>range-hash</algorithm>
</rule>
</tableRule>

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<property name="count">3</property>
</function>
<function name="range-hash" class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">partition-hash-long.txt</property>
</function>

6.3 重要原则:同业务关联表必须统一分片字段

  • 订单、订单项、物流、支付等需要关联查询的表,必须使用相同的分片键和分片规则,否则 JOIN 将跨库,性能极差甚至报错。
  • 毫无关联的独立表(如用户表按 uid 分,日志表按 id 分)允许不同。

正确示例:订单表和订单详情表都按user_id分片,且共用user_rule,联表时数据在同一个库,性能高。

<!-- 两张表都使用同一个 user_rule,分片键都是 user_id -->
<table name="t_order" dataNode="dn1,dn2" rule="user_rule" primaryKey="id"/>
<table name="t_order_item" dataNode="dn1,dn2" rule="user_rule" primaryKey="id"/>

同时,物理表中必须都包含user_id字段,否则 Mycat 无法正确路由。

CREATE TABLE t_order (id INT, user_id INT, ...);
CREATE TABLE t_order_item (id INT, user_id INT, order_id INT, ...);

7. 垂直分表的插入与查询注意事项

垂直分表后,插入数据必须使用两条 INSERT 语句,不能一条 SQL 同时插入两张表

START TRANSACTION;
INSERT INTO t_goods_main(id, goods_name, price) VALUES(1001, '手机', 2999);
INSERT INTO t_goods_ext(goods_id, goods_detail) VALUES(1001, '超长详情...');
COMMIT;

查询时只需要一条联表 SQL(因为两表在同一库,性能很好):

SELECT m.*, e.goods_detail
FROM t_goods_main m
LEFT JOIN t_goods_ext e ON m.id = e.goods_id
WHERE m.id = 1001;

Mycat 在此处只负责将 SQL 路由到正确节点,不做任何自动拆分或合并字段的操作。


8. 四种策略本质对比总结

策略核心操作是否拆分数据是否需要 rule分片键位置Mycat 参与度
垂直分库不同表存不同库不需要按配置路由表到指定节点
水平分库同一张表数据散列到多个库必须rule 的 <columns>自动分片路由
垂直分表同库内一张表拆成多张表(字段拆分)不需要只登记表位置,拆分人为完成
水平分表同库内逻辑表拆成多张物理子表必须rule 的 <columns>自动路由到正确的子表
http://www.jsqmd.com/news/1163605/

相关文章:

  • 无货源自动拍单怎么选?重点看订单同步、货源关联、物流回传,抖掌柜一站式搞定 - 抖掌柜
  • 2026年通化GEO系统贴牌服务商靠谱源头厂商综合实力推荐TOP3:支持OEM贴牌、技术加盟的合作路径怎么选? - 科技快讯
  • AI Agent 面试题 686:Agent对齐(Alignment)的核心挑战和解决方案
  • 单调栈理解和实战
  • 远程操控自动机场起降,拼的不是胆量,而是系统
  • GRSL 2026 即插即用 | Transformer篇 | FEFFN:频域 - 空域联合建模,跨频交互,全局结构 + 局部细节全保留,根治传统 FFN 空间建模缺失
  • 2026 年现阶段,桥东值得关注的休息亭品牌哪家可靠,原来公园最舒服的不是长椅,而是这不起眼的角落。 - 企业官方推荐【认证】
  • elasticsearch学习笔记(三十五)——Elasticsearch 索引管理
  • 2026年7月沈阳​市公共卫生许可证检测集中空调通风系统检测水质检测空气质量甲醛检测怎么做?正规CMA机构办理指南 - 绿呼吸检测中心
  • 天津黄金回收指南:9种情况对号入座找对品牌不踩坑 - 资讯纵览
  • mysql-SQL语句执行过程
  • WebPShop:为Photoshop用户解锁专业级WebP图像处理能力
  • elasticsearch学习笔记(三十四)——Elasticsearch 基于scoll技术滚动搜索大量数据
  • 2026年7月衢州​市公共卫生许可证检测集中空调通风系统检测水质检测空气质量甲醛检测怎么做?正规CMA机构办理指南 - 绿呼吸检测中心
  • 2026年7月十堰​市公共卫生许可证检测集中空调通风系统检测水质检测空气质量甲醛检测怎么做?正规CMA机构办理指南 - 绿呼吸检测中心
  • AI 习惯追踪的反馈设计:鼓励不是堆砌赞美,而是记录可见进步
  • 基于MKV42F128VLH16与PAM8904的低功耗警报系统设计
  • 2026英语写作批改工具选型指南:行业痛点与AI技术路径深度解析
  • 2026年7月绍兴​市公共卫生许可证检测集中空调通风系统检测水质检测空气质量甲醛检测怎么做?正规CMA机构办理指南 - 绿呼吸检测中心
  • 2026年7月最新昆明欧米茄官方售后热线及客户服务网点地址 - 欧米茄服务中心
  • 2026年赤峰GEO系统贴牌服务商靠谱源头厂商综合实力推荐:本地合伙人如何选对OEM贴牌与技术加盟合作路径? - 小随科技
  • 2026年 软考备考指南及考前题型
  • 长沙黄金回收选哪家?这家全国连锁,不踩坑 - 小蝶回收测评
  • 2026年7月石家庄​市公共卫生许可证检测集中空调通风系统检测水质检测空气质量甲醛检测怎么做?正规CMA机构办理指南 - 绿呼吸检测中心
  • 四 、SCI常用性能表达词
  • elasticsearch学习笔记(三十三)——Elasticsearch Bouncing Results问题
  • STM32F405ZG与ADS131M02高精度ADC系统设计指南
  • 安科瑞面向购物中心 / 写字楼停车场 全场景充电桩智能运营整体解决方案
  • 2026最新卖家精灵优惠码最新汇总:单人版KJDSYY72、标准版及以上KJDSYY78 - 跨境电商卖家出海
  • QString完整详解