贝利信息

SQL 水平拆分与垂直拆分的取舍

日期:2026-01-25 00:00 / 作者:冰川箭仙
水平拆分适用于单表数据量达千万至亿级导致查询慢、主从延迟高、备份恢复慢等场景,需自行处理路由、聚合、全局统计及分布式ID;垂直拆分则按列分离冷热数据或更新频率差异大的字段,降低I/O与锁竞争,不改变查询逻辑;混合拆分常见但复杂度高,须统一元数据管理。

水平拆分适合单表数据量爆炸,但得自己管路由和聚合

当一张表超过千万甚至上亿行,查询变慢、主从延迟拉高、备份恢复耗时,这时候水平拆分(Sharding)才真正有用。它把同一张表的数据按某种规则(比如 user_id % 4)分散到多个物理库/表中,每份只存一部分数据。

但代价明显:你得在应用层或中间件里实现分片键识别、SQL 路由、跨分片 JOINGROUP BY 的结果合并;SELECT COUNT(*) 这种全局统计必须改写成多节点并发查再汇总;自增主键基本废掉,得换 UUID 或雪花算法。

常见踩坑点:

垂直拆分解决耦合与冷热分离,但别拆过头

垂直拆分是把一张宽表按列拆成多张逻辑相关的表,比如把 user 表拆成 user_base(登录名、密码)、user_profile(昵称、头像)、user_stats(积分、等级)。目标是降低单表宽度、减少

I/O、隔离读写压力、方便按需扩缩容。

它不碰行数,所以不用改查询逻辑,也不影响主键和事务。但拆得不合理会引入大量关联查询,反而加重数据库负担。

实用建议:

先垂直,再水平;能不拆,就不拆

90% 的性能问题其实出在索引缺失、慢 SQL、连接池配置或硬件瓶颈,而不是数据量本身。上线前先做压测,确认单库单表真扛不住了,再考虑拆分。

拆分顺序有现实约束:

混合拆分常见但容易失控,必须有统一元数据管理

真实系统往往是混合模式:用户中心垂直拆成几张表,其中 user_order 又按 user_id 水平拆了 8 个库。这种组合放大了复杂度——你既要维护字段归属关系,又要管理分片映射、跨库事务边界、分布式唯一 ID 生成策略。

最容易被忽略的点是元数据同步:

真正难的从来不是怎么拆,而是拆完之后,怎么让所有人(开发、DBA、运维)对“这张表现在在哪、怎么查、哪些字段属于哪一层”保持一致认知。