0

0

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

冰川箭仙

冰川箭仙

发布时间:2026-01-25 19:20:48

|

507人浏览过

|

来源于php中文网

原创

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

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

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

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

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

常见踩坑点:

  • 误把高频关联字段(如 order.user_iduser.id)设成不同分片键,导致跨库 JOIN 不可避免
  • 用时间范围做分片(如按月建表),但业务查的是“最近 7 天订单”,结果要扫 2–3 张表,反而更慢
  • 没预留扩容能力,初始分 4 片,等流量翻倍后发现没法平滑加到 8 片,只能停机迁移

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

垂直拆分是把一张宽表按列拆成多张逻辑相关的表,比如把 user 表拆成 user_base(登录名、密码)、user_profile(昵称、头像)、user_stats(积分、等级)。目标是降低单表宽度、减少 I/O、隔离读写压力、方便按需扩缩容。

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

实用建议:

Mulan AI
Mulan AI

画布式AI视频创作平台,轻松制作爆款视频

下载
  • 优先拆“更新频率差异大”的字段,比如用户密码很少改,但积分每秒都在变,放一起会导致整行锁竞争
  • 把大字段(TEXTBLOB)单独拎出来,避免日常 SELECT * 拖慢所有查询
  • 别为“看着整洁”而拆——例如把 created_atupdated_at 单独建一张表,毫无意义

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

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

拆分顺序有现实约束:

  • 垂直拆分成本低、风险小,能立刻缓解部分压力,适合作为第一阶段动作
  • 水平拆分是“不可逆操作”,一旦开始就绑定分片逻辑,后续所有新功能都要考虑分片语义
  • 很多团队卡在“想水平但不敢动”,最后用读写分离 + 缓存 + 归档老数据撑了两年,发现根本没到非拆不可的地步

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

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

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

  • 新增一个字段,得同步改多个库的 DDL,漏一个就会导致应用报 Unknown column
  • 某个分片库升级了 MySQL 版本,其他没跟上,结果 JSON_EXTRACT 行为不一致,查出来空值
  • 没有集中式分片配置中心,靠配置文件编码分片规则,上线新节点时手动改代码,出错率飙升

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

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

686

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

325

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

348

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1159

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

359

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

758

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

577

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

420

2024.04.29

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

58

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 1.9万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 810人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号