数据库分库分表

分库分表是解决数据库性能瓶颈(数据量大、并发高)的两种主要拆分思路,它们的出发点和实现方式截然不同。

用一个形象的比喻来形容:

  • 垂直拆分 :像一个仓库分区,把不同的货物(用户数据、订单数据、商品数据)放到不同的货架上。
  • 水平拆分 :像一个连锁仓库,把同一种货物(比如所有订单)均匀地分到多个一模一样的仓库里。

下面进行详细拆解。


一、垂直分库分表

核心思想:按业务/功能模块拆分,即"列"的拆分。 将一张宽表,或者一个庞大臃肿的库,拆分成多个结构不同的、更小、更专注的表或库。

1. 垂直分表
  • 是什么 :基于数据库表 的列进行拆分。将一张表中不常用字段长度较大的列拆分到扩展表中。
  • 为什么:解决单表字段过多、数据行过大导致的 I/O 效率低、热点数据访问集中的问题。
  • 怎么做
    • 将核心、高频访问的字段放在主表(如 user_base)。
    • 将不常用、大字段(如详情描述、配置信息)放在扩展表(如 user_detail)。
    • 通过主键(user_id)关联。
  • 例子
    • 拆分前用户表(user_id, username, password, phone, avatar, personal_bio, create_time, ...),其中 personal_bio(个人简介)是长文本,不常查询。
    • 拆分后
      • 用户基础表(user_id, username, password, phone, avatar, create_time)
      • 用户详情表(user_id, personal_bio, ...)
  • 示例
2. 垂直分库
  • 是什么 :基于业务维度 ,将不同的 分散到不同的数据库中。每个库可以部署在不同的服务器上。
  • 为什么:解决单库并发压力大、不同业务争抢资源的问题。实现业务解耦,便于独立扩展和维护。
  • 怎么做
    • 按业务领域划分,如电商系统分为:用户库、订单库、商品库、支付库等。
  • 例子
    • 拆分前 :所有表都在一个 ecommerce_db 中。
    • 拆分后
      • user_db:存放用户、地址等表。
      • order_db:存放订单、购物车等表。
      • product_db:存放商品、品类、库存等表。
  • 示例

    垂直拆分的优缺点
  • 优点
    • 业务清晰,解耦。
    • 便于针对不同业务进行优化和管理(如订单库用 SSD,日志库用 HDD)。
    • 高并发场景下,能分散数据库压力。
  • 缺点
    • 单表/单库数据量过大的问题依然存在(垂直分表后,主表数据仍可能快速增长)。
    • 可能带来跨库事务(分布式事务)问题,复杂且性能损耗大。
    • 无法解决单业务模块的数据量级爆炸问题(如订单表达到十亿级)。

二、水平分库分表

核心思想:按数据行拆分,即"行"的拆分。 将同一个表结构的数据,分散到多个表或多个库中。

1. 水平分表
  • 是什么 :在同一个数据库 中,将一张表的数据按某种规则拆分到多个结构相同的表中。
  • 为什么:解决单表数据量过大(如 > 5000万行)导致的查询慢、索引膨胀问题。
  • 怎么做 :需要选定一个分片键(Sharding Key) ,并制定路由规则。
    • 常见分片键:用户ID、订单ID、时间等。
    • 常见路由规则
      • 取模分表序号 = user_id % 分表总数。例如,分4张表,user_id=5的数据落在 user_5 % 4 = 1,即 user_1表。
      • 范围user_1 表存 1-1000万,user_2 表存 1000万-2000万。
      • 哈希:对分片键做哈希运算后取模。
  • 例子订单表user_id 取模,拆分到 order_0, order_1, order_2, order_3 四张表中。
  • 示例:
2. 水平分库分表
  • 是什么 :水平分表的升级版,将数据分散到多个数据库的多个表中。这是最彻底的拆分方式。
  • 为什么:同时解决单表数据量过大和单库(连接数、I/O、CPU)瓶颈问题。
  • 怎么做 :需要同时选择 分库策略分表策略
    • 常见做法:先按分片键决定去哪个库,再决定去哪个表。
  • 例子 :将订单数据分到 2 个库,每个库 4 张表,共 8 个分片。
    • 路由规则:库序号 = (order_id % 8) / 4表序号 = order_id % 4
    • order_id = 1717 % 8 = 11 / 4 = 0(库0),17 % 4 = 1(表1),最终落在 db_0.order_1
  • 示例

水平拆分的优缺点

  • 优点
    • 根本性解决了大数据量存储和访问的性能问题
    • 理论上可以无限横向扩展。
  • 缺点
    • 复杂度急剧上升:分片规则设计、数据迁移、扩容(如从2库扩容到3库)非常复杂。
    • 跨分片查询(如范围查询、聚合查询)变得异常困难,通常需要合并多节点数据,或在应用层处理。
    • 跨分片事务几乎无法实现,需依赖最终一致性方案。

三、核心区别与如何选择

特性 垂直拆分 水平拆分
拆分维度 业务/列(不同数据) 数据行(相同结构的数据)
目标 解耦、降低单库并发压力 解决海量数据存储和访问压力
粒度 较粗(以表或库为单位) 很细(以数据行为单位)
影响范围 影响多个业务模块,改动较大 影响单个业务模块,但该模块内改动深
拓展性 库级别扩展,有上限 理论上可无限水平扩展
典型场景 微服务架构、业务清晰的系统 单表数据超亿,高增长的业务(如交易、日志)

四、综合实践与建议

在实际大型系统中,垂直拆分和水平拆分通常是结合使用的

  1. 先垂直,后水平

    • 首先进行垂直分库,按业务拆分(用户、订单、商品)。
    • 当某个业务库(如订单库)的数据量或并发量达到瓶颈时,再对该库内的核心表进行水平分库分表 (如按 user_id 分片订单表)。
  2. 分片键是灵魂:水平拆分时,选择分片键至关重要。它应该满足:

    • 数据均匀:保证数据能均匀分布,避免"数据倾斜"。
    • 查询携带 :尽可能让核心查询(如根据订单ID查详情)都带上分片键,实现单分片查询,避免跨分片扫描。
  3. 使用中间件 :自行实现分库分表逻辑非常复杂,推荐使用成熟的数据库中间件,如:

    • 代理模式:MyCat、ProxySQL、DBProxy。
    • 客户端模式:ShardingSphere-JDBC(Java应用集成)、TDDL。
    • 云服务:阿里云PolarDB-X、腾讯云TDSQL等。

总结来说:垂直拆分是"分类",解决耦合和资源争用;水平拆分是"分散",解决绝对数据量的瓶颈。 架构设计需要根据业务发展阶段,循序渐进地采用合适的拆分策略。

相关推荐
DBA小马哥2 小时前
金仓数据库引领国产化替代新范式:构建高效、安全的文档型数据库迁移解决方案
数据库·安全·mongodb·dba·迁移学习
努力的小陈^O^3 小时前
问题:Spring循环依赖问题排查与解决
java·开发语言·前端
企业对冲系统官3 小时前
基差风险管理系统日志分析功能的架构与实现
大数据·网络·数据库·算法·github·动态规划
冉冰学姐3 小时前
SSM学毕电设信息采集系统74v6w(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·学生管理·ssm 框架应用·学毕电设·信息采集系统
茁壮成长的露露3 小时前
MongoDB备份恢复工具mongodump、mongorestore
数据库·mongodb
HehuaTang3 小时前
requests 调大并对齐 limits 提升POD高负载场景下性能
java·docker·kubernetes
香气袭人知骤暖3 小时前
SQL慢查询常见优化步骤
android·数据库·sql
Star Learning Python3 小时前
MySQL日期时间的处理函数
数据库·sql
JosieBook3 小时前
【数据库】多模融合,智启新篇:金仓数据库重塑国产文档数据库范式
数据库