垂直分库与垂直分表详解

垂直分库与垂直分表详解

垂直分库:按业务域拆分

垂直分库是将一个单一的数据库实例按业务模块拆分为多个独立的数据库实例,每个数据库只负责一个业务域。

典型拆分方式

电商系统单体数据库
├── user 用户模块
├── order 订单模块
├── product 商品模块
├── payment 支付模块
├── coupon 营销模块
└── message 通知模块

拆分为
user_db用户库):useruser_addressuser_login_log
order_db订单库):orderorder_itemreturn_request
product_db商品库):productproduct_skucategory
payment_db支付库):paymentrefund
marketing_db营销库):couponactivity
message_db消息库):messagenotification

为什么要垂直分库

  1. 业务解耦:不同业务模块可以独立开发、部署、扩展。订单系统的故障不会影响商品浏览。

  2. 资源隔离:每个数据库独享连接池和 IO 资源,避免相互干扰。秒杀活动对用户库的冲击不会影响订单写入。

  3. 独立扩容:订单库负载高时,可以单独升级订单库的硬件或增加只读副本。

  4. 数据安全与权限控制:不同团队管理不同的数据库,便于权限管控。

垂直分库带来的挑战

  • 跨库查询:JOIN 操作无法跨库,需要应用层组合数据或采用代码级别的聚合
  • 分布式事务:跨库的数据一致性需要 XA 或 TCC 等方案保障
  • 跨库统计:报表统计需要汇总多个数据库的数据
// 跨库查询的应用层实现
User user = userDbQuery(userId);
List<Order> orders = orderDbQuery(userId);
// 应用层组装
UserVO vo = new UserVO(user, orders);

垂直分表:按字段拆分

垂直分表是将一个字段数较多的表按字段使用频率和数据类型拆分为多个结构不同的关联表。

拆分策略

拆分时将字段分为三组:

  • 高频组:每次查询都需要的字段(小字段)
  • 低频组:偶尔查询的字段
  • 大字段组:TEXT/BLOB 等占用空间大的字段
-- 原始文章表
article(
  id, title, summary, content TEXT, 
  cover_url, category_id, status,
  author_id, view_count, comment_count,
  seo_keywords, ext_meta VARCHAR(5000),
  created_at, updated_at
)

-- 拆分后
-- 主表(高频字段)
article_main(id, title, summary, 
             category_id, status, author_id,
             view_count, comment_count, 
             created_at, updated_at)

-- 内容表(大字段)
article_content(article_id, content, cover_url)

-- 扩展表(低频字段)
article_extra(article_id, seo_keywords, ext_meta)

为什么要垂直分表

  1. 减小单行大小:InnoDB 一页(16KB)能存放更多行,降低 IO 次数
  2. 冷热分离:高频访问的小字段在 buffer pool 中更密集,提高缓存命中率
  3. 避免 IO 放大:查询主表字段时不需要读取 content 等大字段所在的页面
一页 16KB 存 1 行(含 TEXT) vs 一页 16KB 存 100 行(仅 main 字段)
→ 查询 title 时,后者 buffer pool 命中率显著更高

垂直分表的挑战

  • 需要额外的 JOIN 来获取完整数据
  • 事务中更新多张表需要保证一致性
  • 应用代码复杂度增加

垂直拆分的最佳实践

  1. 先分析业务和查询模式:梳理高频查询涉及的字段,避免拆分后查询反而需要关联多表
  2. 分表时使用相同的主键类型:确保关联查询效率
  3. 控制拆分粒度:不是表越细越好,2-3 张表通常已经足够
  4. 虚拟列或视图辅助:MySQL 的视图或虚拟列可以帮助简化应用层查询
  5. 结合读写分离:主表走主库,扩展表可以走从库

垂直拆分 vs 反范式化

垂直拆分是一种”范式化”操作——把原来宽表拆分成多个窄表。但有时候反其道而行之(适当的反范式化,将常用 Join 表合并)反而性能更好。需要根据实际查询模式权衡。

面试要点

  • 垂直分库解决的是”业务耦合”和”资源共享”问题
  • 垂直分表解决的是”单行太大”和”冷热数据混存”问题
  • 两者的本质都是按”列”的维度切分(而非”行”)
  • 垂直分库后的跨库事务是引入的最大复杂度
  • 垂直分表时选择合适的主键关联策略很重要
© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容