2. 水平分区 vs 垂直分区:两种基本分区方式的原理与对比
分区这件事,说白了就是把一张大表拆成多张小表来管理。但怎么拆?拆成行还是拆成列?这就是我们今天要聊的核心问题。
我个人习惯把分区策略分成两大类:水平分区和垂直分区。这两种方式看似简单,但选错了,性能反而会下降。我在项目中见过不少团队,一上来就搞水平分区,结果查询还是慢——因为根本没用对场景。
2.1 水平分区:按行切分
水平分区,就是把一张表的数据行,按照某个规则分散到多个物理存储单元中。每个分区里的表结构完全一样,只是数据不同。
举个例子,一张用户表有 1 亿行数据。按用户 ID 取模,分成 10 个分区。每个分区存 1000 万行。查询时只扫一个分区,速度自然快。
核心原理:水平分区 = 按行拆分,每个分区是原表的子集。
2.1.1 常见的水平分区策略
- 范围分区:按时间、ID 范围划分。比如按月份分区,1 月数据放分区 1,2 月数据放分区 2。
- 哈希分区:对分区键做哈希运算,均匀分布数据。适合没有明显范围特征的场景。
- 列表分区:按枚举值划分。比如按地区,华东、华北各一个分区。
嗯,这里要注意:范围分区容易产生数据倾斜。我记得有一次做订单表分区,按月份分,结果双十一那个月的数据量是其他月份的 10 倍。单个分区压力太大,查询反而变慢了。
2.1.2 水平分区的优缺点
| 优点 | 缺点 |
|---|---|
| 提升查询性能(只扫描相关分区) | 跨分区查询需要合并结果 |
| 方便数据归档(直接删除分区) | 分区键选择不当会导致数据倾斜 |
| 支持并行处理(多分区同时扫描) | 分区数量过多会增加元数据开销 |
| 扩展性好(增加分区即可扩容) | 跨分区事务处理复杂 |
2.2 垂直分区:按列切分
垂直分区,是把一张表的列拆开,放到不同的表中。每个垂直分区包含原表的部分列,但行数相同。
你想想看,一张用户表有 50 列,但业务查询经常只用到其中 5 列。每次查询都要把 50 列全部读出来,IO 开销很大。垂直分区就是解决这个问题的。
我的经验:垂直分区特别适合「宽表」场景。我曾经处理过一张 200 列的设备日志表,每次查询只需要 10 列。垂直分区后,查询速度提升了 5 倍以上。
2.2.1 垂直分区的两种模式
- 按访问频率拆分:高频访问的列放一个分区,低频访问的列放另一个分区。
- 按数据类型拆分:固定长度字段放一个分区,变长字段放另一个分区。这样能提高存储效率。
为什么会这样?因为数据库是按页存储的。如果一张表里既有 tinyint 又有 text 字段,text 字段会占用大量空间,导致每页能存放的行数减少。垂直分区后,固定长度字段的扫描效率会明显提升。
2.2.2 垂直分区的优缺点
| 优点 | 缺点 |
|---|---|
| 减少 IO 读取量(只读需要的列) | 需要 JOIN 才能还原完整数据 |
| 提高缓存命中率(热点列更紧凑) | 事务更新涉及多个分区时更复杂 |
| 便于权限控制(敏感列单独管理) | 拆分粒度不好控制,过细反而增加复杂度 |
| 优化存储效率(同类数据放一起) | 不适合频繁全列查询的场景 |
2.3 水平分区 vs 垂直分区:核心对比
这两种方式不是互斥的,实际项目中经常组合使用。但理解它们的本质区别,才能做出正确选择。
| 对比维度 | 水平分区 | 垂直分区 |
|---|---|---|
| 拆分对象 | 行 | 列 |
| 分区结构 | 每个分区结构相同 | 每个分区结构不同 |
| 主要目的 | 解决数据量过大 | 解决列数过多 |
| 查询特点 | 适合范围查询、全表扫描 | 适合点查询、列子集查询 |
| 数据倾斜风险 | 高(分区键选择不当) | 低(按列拆分,行数一致) |
| 跨分区操作 | 需要 UNION ALL | 需要 JOIN |
| 典型场景 | 日志表、订单表 | 用户画像表、配置表 |
避坑指南:我曾经在一个项目中,把一张 30 列的表做了垂直分区,拆成了 5 个小表。结果业务方每次查询都要 JOIN 4-5 张表,性能反而下降了。垂直分区不是拆得越细越好,拆到 2-3 个分区通常就够了。
2.4 如何选择?我的决策框架
在实际项目中,我一般按以下步骤来判断:
- 先看数据量:单表超过 500 万行,优先考虑水平分区。
- 再看列数:单表超过 30 列,且查询经常只用到部分列,考虑垂直分区。
- 看访问模式:如果查询经常需要全行数据,水平分区更合适;如果只查少数列,垂直分区收益更大。
- 看写入模式:写入集中在某个范围(比如最近 7 天),范围分区很合适;写入随机分布,哈希分区更均衡。
嗯,这里有个小技巧:先做垂直分区,再做水平分区。先把宽表拆成窄表,再对数据量大的窄表做水平分区。这样组合使用,效果往往最好。
2.5 知识体系图
下面这张图展示了水平分区和垂直分区的核心逻辑,以及它们在实际应用中的关系:
2.6 小结
水平分区和垂直分区,是分区策略的两大基石。水平分区解决「行太多」的问题,垂直分区解决「列太多」的问题。选对方式,性能提升立竿见影;选错了,反而会引入不必要的复杂度。
我个人建议:先评估数据特征,再选分区方式。不要为了分区而分区,每个分区策略都应该有明确的业务目标。