什么是垂直拆分和冷热数据拆分?如何判断该不该拆?
简化版
垂直拆分是按字段访问频率或业务边界把一张宽表拆成多张表;冷热数据拆分是把高频访问的数据和低频历史数据分开存放。是否拆分要看行宽、访问频率、查询路径、数据增长、索引大小和维护复杂度,不要为了“看起来规范”盲目拆。
详细版
常见拆分方式:
- 字段级垂直拆分:用户基础表 + 用户扩展表;
- 业务边界拆分:订单主表 + 订单明细表 + 支付表;
- 冷热拆分:近 3 个月订单在热表,历史订单进归档表;
- 大字段拆分:文章列表字段和正文内容分表。
拆分收益:
- 热表行更窄,单页能放更多记录;
- 索引更小,缓存命中更高;
- 高频查询减少无用字段读取;
- 历史数据归档更容易。
拆分代价:
- 查询需要 JOIN 或二次查询;
- 写入事务更复杂;
- 数据一致性和迁移成本增加;
- 代码模型更复杂。
完整版教学
一、为什么宽表会拖慢热点查询
数据库通常按页读取数据。行越宽,一个页能放的行越少。即使你只查列表字段,只要这些字段和大字段在同一行里,也可能影响缓存效率和 I/O。
比如文章表里既有标题、作者、发布时间,又有超长正文、审核备注、扩展 JSON。首页列表只需要标题和摘要,却让热点查询背着冷字段一起生活,这就不划算。
二、垂直拆分按访问频率切
用户表常见拆法:
user_base(id, nickname, avatar, status)
user_profile(user_id, birthday, intro, address)
user_security(user_id, password_hash, last_login_ip)
基础信息高频展示,资料信息低频访问,安全字段权限敏感。拆开后,每张表职责更清楚,热点查询更轻。
三、冷热拆分按时间和活跃度切
订单系统中,最近 3 个月订单访问频繁,三年前订单很少访问。把全部订单都放一张表里,索引和统计都越来越重。
可以把近期订单留在热表,历史订单归档到历史表或冷存储。这样热表保持较小规模,高频查询更稳定。
冷热拆分要设计好查询入口:用户查历史订单时,系统要知道去历史表查;后台统计也要知道冷热两边都要汇总。
四、拆分不是越细越好
拆得太细会带来很多问题:
- 读一个页面要查多张表;
- 事务跨表变复杂;
- 接口拼装成本上升;
- ORM 模型更重;
- 数据迁移更麻烦。
如果表不大、查询简单、性能没有瓶颈,强行拆分只是提前制造复杂度。
五、判断该不该拆的信号
可以关注这些信号:
- 表行很宽,大字段拖累高频查询;
- 热点查询只用少数字段;
- 历史数据占大头,近期数据访问占绝大多数;
- 索引过大,Buffer Pool 缓存效率下降;
- 归档、备份、清理越来越困难;
- 不同字段权限和生命周期明显不同。
这些信号越多,拆分越有价值。
六、拆分前要设计迁移路径
拆表不是只改 DDL。还要考虑:
- 历史数据如何迁移;
- 双写期间如何保持一致;
- 旧接口如何兼容;
- 回滚方案是什么;
- 线上查询是否需要灰度;
- 统计报表是否受影响。
成熟的拆分方案一定包含迁移和验证,而不只是新表结构。
判断冷热窗口时最好用访问数据说话。比如订单查询日志显示 92% 的用户查询集中在近 90 天,99% 集中在近 1 年,那么可以把近 90 天放热表,1 年内放温数据,超过 1 年归档;如果客服和财务经常查 3 年历史,冷热边界就不能只按用户端访问来定。
七、常见误区与追问
| 拆分类型 | 拆分依据 | 典型例子 |
|---|---|---|
| 垂直拆分 | 字段访问频率、权限、业务边界 | 用户基础表 + 用户扩展表 |
| 大字段拆分 | 行宽和 I/O 成本 | 文章列表表 + 正文表 |
| 冷热拆分 | 时间、活跃度、生命周期 | 近 3 个月订单热表 + 历史订单表 |
易错点:拆表的目标是让高频路径更轻,不是让 ER 图更复杂。拆完后如果每次请求都要多查 3 张表,可能只是把问题从存储层搬到了应用层。
用页容量粗算一下:假设数据库页大小 16KB,一行热点字段 200B,如果不带大字段,一页大约能放 16KB / 200B ≈ 80 行;如果同表混入 2KB 正文字段,一页可能只能放 16KB / 2200B ≈ 7 行。首页列表只查标题时,后一种设计会显著降低缓存命中和扫描效率。
- 误区:宽表一定要拆。 如果数据量小、查询简单、没有性能瓶颈,宽表可能更直接,过早拆分会增加复杂度。
- 误区:冷热拆分只按时间切就行。 时间是常见依据,但还要看访问热度、合规保留、归档查询和统计口径。
- 误区:垂直拆分后性能一定提升。 如果业务每次都需要 JOIN 回所有字段,拆分收益会被额外查询成本抵消。
- 追问:大字段为什么适合单独拆? 大字段会拉宽行、降低页内行数和缓存效率,高频列表通常不需要它。
- 追问:冷热表查询入口怎么设计? 普通查询默认热表,历史查询明确进入归档表,跨冷热统计要有汇总表或异步数仓支持。
- 追问:拆分上线如何降低风险? 通常要先建新表、迁移历史、双写校验、灰度读新表、保留回滚窗口,再切全量流量。
八、加强记忆
垂直拆分按字段和业务边界拆,冷热拆分按访问热度和时间拆。拆分能让热表更窄、索引更小、缓存更友好,但会增加 JOIN、事务和迁移复杂度。该不该拆,看访问模式和增长压力,不看“表多不多”。