分区和分表有什么区别?

#中间件#面试八股

分区和分表有什么区别?

结论:分区(Partition)是数据库内核把一张逻辑表的数据按规则分散到多个物理文件,SQL 不变、由优化器做分区裁剪(Partition Pruning);分表(Sharding)是应用层或中间件把一张表拆成多张独立表,SQL 必须按规则改写。分区不跨实例,突破不了单机上限;分表可以跨库,但要自己承担路由与归并。

一、对比表

维度分区(Partition)分表(Sharding)
执行者数据库内核应用或中间件
SQL 是否改写否是(库名、表名)
是否跨实例否,仍是单库单机可以,分库即跨实例
事务单机本地事务跨库需分布式事务
索引每个分区独立索引,全局唯一索引受限每表独立,天然无全局约束
运维一条 ALTER 管全部分区需逐表变更
扩容受单机资源限制可加机器线性扩展
典型用途按时间归档、快速清理海量数据、高并发写入

二、分区的工作方式

                 t_order(逻辑上一张表)
   ┌──────────┬──────────┬──────────┬──────────┐
   │ p2025q1  │ p2025q2  │ p2025q3  │  pmax    │
   │ 独立 ibd │ 独立 ibd │ 独立 ibd │  兜底    │
   └──────────┴──────────┴──────────┴──────────┘
   WHERE create_time >= '2025-07-01'
        └── 优化器裁剪:只扫 p2025q3 与 pmax

MySQL 支持 RANGE、LIST、HASH、KEY 四类分区;8.0 起支持 RANGE COLUMNS 直接用日期或字符串列做分区键。

三、建表与配置

CREATE TABLE t_order (
  id          BIGINT UNSIGNED NOT NULL,
  user_id     BIGINT UNSIGNED NOT NULL,
  amount      DECIMAL(12,2)   NOT NULL,
  create_time DATETIME        NOT NULL,
  PRIMARY KEY (id, create_time)          -- 分区键必须包含在每个唯一键中
) ENGINE=InnoDB
PARTITION BY RANGE COLUMNS (create_time) (
  PARTITION p2025q1 VALUES LESS THAN ('2025-04-01'),
  PARTITION p2025q2 VALUES LESS THAN ('2025-07-01'),
  PARTITION p2025q3 VALUES LESS THAN ('2025-10-01'),
  PARTITION pmax    VALUES LESS THAN (MAXVALUE)
);

-- 清理历史数据:秒级完成,不产生大事务,不锁全表
ALTER TABLE t_order DROP PARTITION p2025q1;

-- 查看裁剪效果
EXPLAIN SELECT * FROM t_order WHERE create_time >= '2025-08-01' AND create_time < '2025-09-01';
-- partitions 列会显示 p2025q3,而不是全部

关键限制:分区键必须出现在表的所有唯一索引(含主键)里,否则建表直接报错——这就是分区表主键常写成 (id, create_time) 的原因。

四、常见追问

Q1:分区能提升并发吗? 基本不能。所有分区共享同一个实例的缓冲池(Buffer Pool)、redo log 与连接数,锁和 IO 仍是单机资源。只有在查询条件里带上分区键触发裁剪,才能减少扫描量。

Q2:为什么大厂很少用分区表? 一是运维工具链对分区的支持参差,二是分区键一旦选错无法在线修改,三是跨分区查询容易退化为全表扫描。分表的路由完全在应用掌控之内,更灵活也更好排查。

Q3:分区和分表能一起用吗? 可以。实践中常见「先按业务分库分表,再在每个物理表上按时间分区」,用 DROP PARTITION 低成本归档冷数据。

Q4:分区表的主键自增还有效吗? 有效,但自增只在单实例内唯一,跨分表就不再全局唯一,需要改用全局 ID 方案。

Q5:分区表一定比普通表快吗? 不一定。只有查询条件命中分区键、触发裁剪时才快;不带分区键的查询会扫描所有分区再合并结果,反而比单表更慢。

所以分区键的选择标准与分片键一致:查询必带、分布均匀、上线后不可变。

小结

  • 分区是内核行为,SQL 透明、不跨机;分表是架构行为,SQL 需改写、可跨库。
  • 需要突破单机上限就分表;只需要按时间归档清理,分区更省事。
  • 分区键必须进入所有唯一索引,这是建表时最容易踩的坑。
笔记加载中…