当你的单身公寓住不下所有家具时,你会怎么做?搬到大房子或者拆分成多个小仓库!MySQL 的数据也有同样的烦恼...
分库分表是指将原本存储在单个数据库和单张表中的数据,按照特定的规则切分到多个数据库或多个表中,以解决海量数据存储和访问的性能问题。简单来说:当数据量太大,一个"房子"住不下时,要么买更多房子(分库),要么在同一个房子里隔出更多房间(分表)。
场景:拥挤的公寓
数据库:"我实在太拥挤了,每次查询都要翻箱倒柜!"
DBA:"是时候搬家或者做个大扩建了!"
开发者:"但搬家好麻烦啊..."
DBA:"比你的系统崩溃容易处理多了!"
主要原因:
场景:家庭空间规划
家长:"厨房用品放厨房,卧室用品放卧室,不要混在一起!"
数据表:"我们按业务功能分开住,互不干扰!"
做法:按业务模块将不同表拆分到不同的数据库中
案例:用户库、订单库、商品库分开部署
搬家前:
┌────────────────────┐
│ 大杂烩数据库 │
│ ┌──────┐ ┌──────┐ │
│ │用户表 │ │订单表 │ │
│ └──────┘ └──────┘ │
│ ┌──────┐ ┌──────┐ │
│ │商品表 │ │评论表 │ │
│ └──────┘ └──────┘ │
└────────────────────┘
搬家后:
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 用户库 │ │ 订单库 │ │ 商品库 │
│ ┌──────┐ │ │ ┌──────┐ │ │ ┌──────┐ │
│ │用户表 │ │ │ │订单表 │ │ │ │商品表 │ │
│ └──────┘ │ │ └──────┘ │ │ └──────┘ │
└──────────┘ └──────────┘ └──────────┘
做法:将一张表中的列分拆到多张表,常用字段放一起,不常用字段另开表
案例:商品基本信息表、商品详细描述表、商品图片表
分表前:
┌─────────────────── 商品表 ───────────────────┐
│ ID │ 名称 │ 价格 │ 库存 │ 详细描述 │ 图片URL集 │
└─────────────────────────────────────────────┘
分表后:
┌─────── 商品基本表 ──────┐ ┌── 商品描述表 ──┐ ┌── 商品图片表 ───┐
│ ID │ 名称 │ 价格 │ 库存 │ │ ID │ 详细描述 │ │ ID │ 图片URL集 │
└───────────────────────┘ └───────────────┘ └───────────────┘
场景:小区扩建
开发商:"一个小区住不下这么多人,我们再建5个一模一样的!"
居民:"新小区和旧小区户型完全一样,只是地址不同!"
做法:同一个表的数据拆分到不同数据库中
案例:订单库 1、订单库 2、订单库 3...
分库前:
┌────── MySQL实例 ──────┐
│ 订单库 │
│ ┌───────────┐ │
│ │ 订单表 │ │
│ │(1千万数据) │ │
│ └───────────┘ │
└───────────────────────┘
分库后:
┌─── 实例1 ───┐ ┌─── 实例2 ───┐ ┌─── 实例3 ──┐
│ 订单库1 │ │ 订单库2 │ │ 订单库3 │
│ ┌───────┐ │ │ ┌───────┐ │ │ ┌───────┐ │
│ │订单表 │ │ │ │订单表 │ │ │ │订单表 │ │
│ │(300万)│ │ │ │(400万) │ │ │ │(300万)│ │
│ └───────┘ │ │ └───────┘ │ │ └───────┘ │
└────────────┘ └─────────────┘ └───────────┘
做法:同一个数据库中的表拆分成多个表,结构完全相同
案例:订单表_0、订单表_1、...、订单表_9
分表前:
┌────────── 订单表 ─────────┐
│ order_id │ user_id │ ... │
│ 10001 │ 2103 │ ... │
│ 10002 │ 5832 │ ... │
│ ... │ ... │ ... │
└──────────────────────────┘
分表后:
┌── 订单表_0 ─┐ ┌── 订单表_1 ─┐ ┌── 订单表_9 ─┐
│id │user│...│ │id │user│...│ ... │id │user│...│
│...│ .. │...│ │...│ .. │...│ │...│ .. │...│
└────────────┘ └────────────┘ └────────────┘
应用:"订单1234应该放在哪个库?"
路由层:"1234 % 4 = 2,所以放在2号库!"
特点:
应用:"ID为80万的用户应该放哪里?"
路由层:"50万~100万的用户在2号库,所以放2号库!"
特点:
应用:"2023年1月的订单要查哪里?"
路由层:"查订单_202301表就行了!"
特点:
场景:家庭空间规划
家长:"厨房用品放厨房,卧室用品放卧室,不要混在一起!"
数据表:"我们按业务功能分开住,互不干扰!"
0
特点:
所有分片表结构完全相同,就像同一个小区的不同楼栋。
场景:家庭空间规划
家长:"厨房用品放厨房,卧室用品放卧室,不要混在一起!"
数据表:"我们按业务功能分开住,互不干扰!"
1
分片后表结构有差异,就像别墅区和普通住宅区。
场景:家庭空间规划
家长:"厨房用品放厨房,卧室用品放卧室,不要混在一起!"
数据表:"我们按业务功能分开住,互不干扰!"
2
场景:家庭空间规划
家长:"厨房用品放厨房,卧室用品放卧室,不要混在一起!"
数据表:"我们按业务功能分开住,互不干扰!"
3
解决方案:
场景:家庭空间规划
家长:"厨房用品放厨房,卧室用品放卧室,不要混在一起!"
数据表:"我们按业务功能分开住,互不干扰!"
4
解决方案:
场景:家庭空间规划
家长:"厨房用品放厨房,卧室用品放卧室,不要混在一起!"
数据表:"我们按业务功能分开住,互不干扰!"
5
解决方案:
场景:家庭空间规划
家长:"厨房用品放厨房,卧室用品放卧室,不要混在一起!"
数据表:"我们按业务功能分开住,互不干扰!"
6
解决方案:
就像搬家公司,它们帮你处理复杂的路由和迁移:
场景:家庭空间规划
家长:"厨房用品放厨房,卧室用品放卧室,不要混在一起!"
数据表:"我们按业务功能分开住,互不干扰!"
7
就像先在自家隔出更多房间,实在不行再买新房子。
场景:家庭空间规划
家长:"厨房用品放厨房,卧室用品放卧室,不要混在一起!"
数据表:"我们按业务功能分开住,互不干扰!"
8
小别墅住 3 个人,没必要隔出 10 个房间。
场景:家庭空间规划
家长:"厨房用品放厨房,卧室用品放卧室,不要混在一起!"
数据表:"我们按业务功能分开住,互不干扰!"
9
朋友住不同小区,就别老想着办集体 party 了。
"数据库就像是你的房子,当东西太多时,你有两个选择:买更大的房子,或者更好地整理现有空间。分库分表是整理的艺术,而不仅仅是简单地买更多房子。"
—— 匿名架构师
下次面试官问你 MySQL 分库分表,别慌!告诉他:那不过是数据库世界的"乔迁新居"罢了!