一、物理库(真库)
就是实实在在存在硬盘上的数据库。
- 看得见、摸得着:MySQL 实例、PG 库、Oracle 库
- 占磁盘空间、有 IP、有端口、有账号密码
- 是真正存数据的地方
一句话:物理库 = 真实的数据库服务器 / 实例
二、逻辑库(虚库)
在物理库上面,人为分出来的 "逻辑分组"。
比如:一个物理 MySQL 服务器上,你建了:
- user_db(用户库)
- order_db(订单库)
- pay_db(支付库)
这些不是独立的服务器,只是在同一个物理库里,用名字隔开。
一句话:逻辑库 = 物理库里的 "文件夹 / 分组"
三、汇聚库(汇总库)
把 N 个业务库的数据,抽过来汇总、清洗、计算,专门用来做报表 / 大屏 / 分析。
来源可能是:
- 订单库
- 用户库
- 支付库
- 物流库
汇聚库干的事:
- 不影响业务
- 不插单、不改单
- 只做:读 → 清洗 → 汇总 → 统计
一句话:汇聚库 = 专门算总账、做报表的仓库
四、MyCat 的核心原理
MyCat 本质是个 "数据库中间件",站在你的应用和真实数据库之间,假装自己是一个数据库,帮你把请求分发到真正的物理库上。
先举个生活化例子:你去一家超大的奶茶店(应用程序),想点一杯奶茶(数据库查询)。
- 如果店里只有 1 个收银台 + 1 个制作台(单物理库),人多了就排队卡壳;
- 老板把店分成 3 个区域:A 区做水果茶、B 区做奶茶、C 区做咖啡(分库分表),但顾客不想找 3 个收银台,只想找 1 个(MyCat),告诉它 "我要一杯珍珠奶茶",由这个收银台(MyCat)把订单分到 B 区,做完再把结果拿给顾客。
MyCat 解决的核心问题:当单数据库扛不住海量数据 / 高并发时,把数据拆到多个物理库,但对应用来说,还是像访问一个库一样简单。
1. 伪装成 "数据库"(协议兼容)
MyCat 会监听和 MySQL 一样的端口(默认 3306),完全兼容 MySQL 的通信协议。
- 应用程序连接 MyCat 时,就像连接普通 MySQL 一样,用的是相同的账号、密码、SQL 语法;
- 应用完全不知道背后不是一个真实数据库,以为 MyCat 就是 "那个库"。
2. 接收 SQL 请求并解析
MyCat 收到应用的 SQL 后,会做两件事:
- 语法解析 :把 SQL 拆成 "要查什么表、什么字段、条件是什么"(比如
select * from order where user_id=100); - 规则匹配:根据你提前配置的 "分库分表规则"(比如 "按 user_id 取模,0-99 到库 1,100-199 到库 2"),判断这条 SQL 该发给哪些物理库。
3. 分发请求到真实物理库
MyCat 会把解析后的 SQL,改造成适合对应物理库的语句,然后分发:
- 如果是单库请求(比如查 user_id=100 的订单,规则里该去库 2):直接把 SQL 发给库 2;
- 如果是多库请求(比如查所有用户的订单):把 SQL 分别发给库 1、库 2、库 3,并行执行。
4. 汇总结果并返回
- 单库请求:直接把库 2 返回的结果,原样传给应用;
- 多库请求:把库 1、库 2、库 3 返回的结果合并(比如把多个库的订单列表拼在一起),再传给应用。
- MyCat 关键概念(和之前讲的库对应)
- 逻辑库 :MyCat 给应用暴露的 "虚拟库"(比如叫
order_all),应用只认这个; - 物理库 :背后真实的多个数据库服务器(比如 db1、db2、db3),MyCat 知道逻辑库
order_all对应这 3 个物理库; - 分片 :逻辑库下的表(比如
order),被拆成多个 "分片表" 分布在不同物理库(db1.order_0、db2.order_1)。
简单例子
假设你配置了:
- 逻辑库:
shop_db - 物理库:db1(IP:192.168.1.10)、db2(IP:192.168.1.11)
- 分库规则:
order表按order_id % 2分库(偶数到 db1,奇数到 db2)
应用执行:select * from shop_db.order where order_id=101
- MyCat 解析出
order_id=101,101%2=1 → 该查 db2; - MyCat 把 SQL 改成
select * from order where order_id=101发给 db2; - db2 返回结果,MyCat 把结果传给应用;
- 应用全程只知道 "连了 shop_db,查了 order 表",不知道有 db1、db2 存在。
总结
- MyCat 是数据库中间件,核心作用是 "分库分表 + 统一入口",让应用无需感知底层多库;
- 核心流程:伪装数据库接收请求 → 解析 SQL 匹配分库规则 → 分发到物理库 → 汇总结果返回;
- 对应用透明:用和 MySQL 完全一样的方式连接,不用改代码,只需要配置 MyCat 的分库规则。
五、单库请求(最常见、效率最高)
场景举例
假设你配置了:order 表按 user_id % 3 分库(取模):
- user_id 0-99 → 物理库 1(db1)
- user_id 100-199 → 物理库 2(db2)
- user_id 200-299 → 物理库 3(db3)
典型单库请求 SQL
-
select * from order where user_id=150;- 计算:150 % 3 = 0?不,150÷3=50,余数 0 → 对应 db1(也可能是 db2,看你规则),总之只需要查 1 个库;
- MyCat 直接把这条 SQL 发给对应的物理库,拿到结果就返回,不用汇总。
-
update order set status=1 where order_id=10086 and user_id=88;- 有明确的 user_id=88,能精准定位到 db1,只访问 1 个库。
核心特征
- SQL 里有能精准匹配分库规则的条件(比如 user_id、order_id 等分片键);
- 只需要访问 1 个物理库,MyCat 不用做结果汇总,效率和直接访问物理库几乎一样。
六、多库请求(需要汇总、效率稍低)
典型多库请求 SQL
-
select * from order where create_time > '2026-01-01';- 这条 SQL 只有 create_time 条件,没有 user_id(分片键);
- MyCat 不知道该查哪个库,只能把这条 SQL 同时发给 db1、db2、db3;
- 等 3 个库都返回结果后,MyCat 把结果合并(比如把 3 个库的订单列表拼在一起),再返回给应用。
-
select count(*) from order;- 要统计所有订单数量,必须查遍所有物理库(db1+db2+db3);
- MyCat 先让每个库算自己的 count,比如 db1 返回 1000,db2 返回 2000,db3 返回 1500;
- MyCat 汇总:1000+2000+1500=4500,再把 4500 返回给应用。
-
select * from order where user_id in (88, 150, 288);- user_id=88 → db1,user_id=150 → db2,user_id=288 → db3;
- 需要访问 3 个库,MyCat 拿到 3 个库的结果后合并返回。
核心特征
- SQL 里没有分片键,或分片键对应多个物理库;
- MyCat 必须 "广播" 请求到所有相关物理库,然后汇总结果;
- 效率比单库请求低(要等多个库响应 + 汇总),这也是分库分表的 "代价"。