垂直拆分与水平拆分的区别

垂直拆分与水平拆分的区别

拆分的两种基本思路

数据库拆分有两种基本维度:垂直拆分(Vertical Sharding)和 水平拆分(Horizontal Sharding)。理解两者的区别是设计可扩展数据库架构的基础。

垂直拆分

垂直拆分按”功能模块”或”字段”来拆分,将一个库/表拆分成多个库/表。

垂直分库

将一个数据库拆分成多个独立的数据库实例,每个实例负责一个业务域:

【原来】一个数据库包含所有表
┌─────────────────────────────┐
│  user_db (单库)             │
│  ├─ user                     │
│  ├─ order                    │
│  ├─ product                  │
│  └─ payment                  │
└─────────────────────────────┘

【拆分后】按业务域分库
┌──────────┐ ┌──────────┐ ┌──────────┐
│ user_db  │ │ order_db │ │ product  │
│  ├─ user  │ │  ├─ order │ │  ├─product│
│  ├─ login │ │  ├─ return│ │  └─...    │
│  └─ ...   │ │  └─ ...   │ └──────────┘
└──────────┘ └──────────┘

垂直分表

将一个字段较多的表拆分成两个或多个表:

-- 原表: user 表(包含所有字段)
user(id, name, email, phone, avatar, intro, address, login_ip, register_time, ... )

-- 拆分后:
-- 主表: 高频访问字段
user_main(id, name, email, phone, register_time)
-- 扩展表: 低频访问的大字段
user_ext(id, user_id, avatar, intro, address, login_ip)

水平拆分

水平拆分按”数据行”来拆分,将同一个表的数据分散到多个结构和原表完全相同的表中。

水平分表

-- 原来: 一张 order 表存所有订单
order(id, user_id, amount, status, ...) -- 1 亿行

-- 水平拆分后: 按 user_id 取模分 10 张表
order_0, order_1, order_2, ... , order_9
-- 每张表约 1000 万行,结构完全相同

水平分库

将数据不仅分表,还分散到不同的数据库实例中:

order_db_0                 order_db_1
┌──────────────────┐       ┌──────────────────┐
│ order_0, order_1 │       │ order_5, order_6  │
│ order_2, order_3 │       │ order_7, order_8  │
│ order_4           │       │ order_9           │
└──────────────────┘       └──────────────────┘

核心区别对比

维度 垂直拆分 水平拆分
拆分依据 功能模块或字段 数据行
目标 解耦业务、缩小单表宽度 分散数据量
数据结构 拆分后表/库结构不同 拆分后结构完全相同
数据量 不直接减少数据量 直接减少单表行数
跨节点Join 不可避免 不可避免
复杂度 相对较低 较高
适用场景 业务模块清晰、表字段多 数据量大、写入吞吐高

各自优缺点

垂直拆分

优点
– 业务解耦,各业务独立扩展
– 单表宽度减小,查询效率提升
– 冷热数据分离(大字段分离)

缺点
– 跨库 JOIN 不可避免
– 分布式事务问题
– 仍然解决不了单表数据量过大的问题

水平拆分

优点
– 单表数据量可控,查询性能稳定
– 可线性扩展,加机器即可扩容
– 写入负载分散到多个节点

缺点
– 跨节点查询复杂(排序、分页、聚合)
– 全局唯一 ID 成为新问题
– 分布式事务难处理
– 扩缩容时需要数据重分布

如何选择

先做垂直,再做水平,这是常见的演进路径:

  1. 初期的垂直拆分:按业务域分库,按字段频度分表
  2. 后续的水平拆分:当单一业务表数据量过大时,再对其做水平拆分

当以下条件成立时,优先水平拆分
– 数据量已经某张表特别大(千万级以上)
– 表字段数量合理(不需要垂直拆分)
– 有合适的分片键

当以下条件成立时,优先垂直拆分
– 业务模块间的耦合度低
– 存在大量宽表(字段数 > 30 个)
– 业务需要独立扩展不同的模块

面试要点

  • 垂直和水平拆分是完全不同的维度,可以组合使用
  • 垂直拆分解决”表太宽”和”业务耦合”问题
  • 水平拆分解决”表太大”和”写入吞吐”问题
  • 在实际项目中通常先垂直后水平,或两者结合
  • 能根据业务场景给出具体的拆分方案和理由
© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容