
垂直分表不是简单地把大表“切开”,而是围绕业务语义和访问模式,把字段按使用频率、更新频率、安全等级、IO 特征等维度进行有策略的分离。核心目标是减少单次查询加载的无效数据、提升缓存命中率、降低锁冲突、便于权限隔离,而不是单纯为了“让表变小”。
按访问频率与更新频率分离热冷字段
一张用户表常包含基础信息(如 nickname、avatar_url)和统计类字段(如 login_count、last_login_time)。前者读多写少、变更频繁;后者读写都较密集且可能被聚合计算频繁更新。若混在同一张表,每次查昵称头像都会连带加载并锁定统计字段,影响并发性能。
- 将高频读取、低频更新的字段(如 user_id、nickname、email、status)保留在主表 user_base
- 将低频读取、高频更新或计算开销大的字段(如 total_amount、order_count、score_rank)拆到 user_stats 表,用 user_id 关联
- 注意:避免跨表 JOIN 查询主场景——若“首页展示用户昵称 + 积分”是高频接口,应考虑冗余关键统计字段(如 current_score),或用应用层双读 + 异步对账保障一致性
按安全与合规要求隔离敏感字段
身份证号、手机号、银行卡号等 PII(个人身份信息)字段,不仅需加密存储,还应从常规业务表中剥离,实现存储隔离、权限收敛和审计可控。
- 新建 user_secure 表,仅含 user_id + 加密后的敏感字段 + 加密版本号 + 更新时间
- 数据库账号按角色授权:业务服务只读 user_base,风控 / 实名认证服务才可访问 user_secure
- 在 ORM 层或 DAO 中封装敏感字段的加解密逻辑,避免裸密出现在 SQL 或日志中
按 IO 特征与大字段类型归类拆分
TEXT、JSON、BLOB 类型字段会显著拉高单行存储体积,导致缓冲池利用率下降、页分裂加剧、备份恢复变慢。即使不常查询,也会拖累整表扫描和索引效率。
- 将富文本简介(profile_desc)、用户上传的头像二进制(avatar_blob)、设备指纹 JSON(device_info)等统一移至 user_ext 表
- user_ext 表可启用压缩行格式(如 InnoDB 的 ROW_FORMAT=COMPRESSED),或对接对象存储(只存 URL)进一步卸载压力
- 查询时严格按需加载:普通列表页不 JOIN ext 表;详情页按需 LEFT JOIN,或用延迟加载(Lazy Load)模式
拆分后必须同步解决的配套问题
垂直分表不是“一拆了之”。缺少协同设计,反而会引入一致性、事务、查询复杂度等新问题。
- 主键强依赖 :所有子表必须以原主表主键(如 user_id)作为主键或唯一外键,禁用自增 ID,确保关联高效、无额外索引膨胀
- 事务一致性 :跨表写入需用本地事务(同一 DB)或 Saga 模式(分布式场景),避免出现 base 表已插入但 secure 表失败的脏状态
- 查询路由透明化 :在 DAO 层或数据访问中间件中封装“逻辑用户表”视图,对外提供统一接口,内部自动路由字段来源,降低业务代码感知成本
- 迁移平滑性 :上线前建新表、双写过渡、校验比对、灰度切流,严禁直接 ALTER TABLE DROP COLUMN






























