「分表」與「分區」同為解決單表過大問題的手段,但本質完全不同。本文從實現方式、數據處理、性能提升側重、實現難度、聯用策略五個維度深度對比,助你選型決策。
| 維度 | 分表 | 分區 |
|---|---|---|
| 本質 | 邏輯上拆分為**多張獨立表**(user_1, user_2...) | 邏輯上仍是**單表**,物理文件按規則拆分(.ibd#P#p0) |
| 應用感知 | 需路由層決定寫哪張表(或用 Merge 引擎透明) | 完全透明,應用仍操作同一表名 |
| 文件結構 | 每張表擁有獨立 .frm/.MYD/.MYI 或 .ibd | 共用一個 .frm,多個 .ibd#P#pN + 一個 .par |
| 主鍵約束 | 各表獨立主鍵,全局唯一需應用層保證(如雪花算法) | 主鍵**必須包含分區鍵**,全局唯一由引擎保證 |
ENGINE=MRG_MyISAM UNION=(t1,t2),插入指定 INSERT_METHOD=LAST,查詢走總表。僅支援 MyISAM,InnoDB 不支援。user_id % N 拼表名。CREATE TABLE orders ( id BIGINT, created_at DATETIME, ... ) ENGINE=InnoDB PARTITION BY RANGE (YEAR(created_at)) ( PARTITION p2020 VALUES LESS THAN (2021), PARTITION p2021 VALUES LESS THAN (2022), PARTITION pmax VALUES LESS THAN MAXVALUE );
| 操作 | 分表 | 分區 |
|---|---|---|
| 歸檔/刪除歷史 | DROP TABLE user_2020 秒級,無 IO 壓力 | ALTER TABLE ... DROP PARTITION p2020 秒級,同等優勢 |
| 跨分片查詢 | 需 UNION ALL 或中間件合併,易產生全表掃描 | 優化器自動分區裁剪,單條 SQL 完成 |
| 熱點遷移 | 需數據雙寫+校驗+切流,複雜度高 | ALTER TABLE ... REORGANIZE PARTITION 在線重組(5.6+) |
| 備份恢復 | 可單表備份,粒度細 | 只能整表備份,或用 xtrabackup 物理備份 |
DROP PARTITION 秒級歸檔。| 指標 | 分表 | 分區 |
|---|---|---|
| 開發改造 | 大(路由層、分布式事務、全局 ID) | 小(僅 DDL 變更,應用無感) |
| 運維複雜度 | 高(幾十/上百張表、Schema 變更同步、統計信息收集) | 低(單表元數據、自動統計、標準 DDL) |
| 擴容靈活性 | 高(新增分表即可,中間件動態感知) | 中(REORGANIZE PARTITION 需鎖表/重建) |
場景:訂單表日增 500 萬,保留 3 年,單表超 50 億行。
user_id 哈希分 64 表(order_00 ~ order_63),解決寫入並發與單表大小。created_at 月度 RANGE 分區,解決歷史歸檔與範圍查詢裁剪。-- 分表 order_00 內部分區示例 CREATE TABLE order_00 ( id BIGINT, user_id BIGINT, created_at DATETIME, ... ) ENGINE=InnoDB PARTITION BY RANGE (YEAR(created_at)*100 + MONTH(created_at)) ( PARTITION p202301 VALUES LESS THAN (202302), ... PARTITION pmax VALUES LESS THAN MAXVALUE );
優勢:寫入分散到 64 表並發,查詢按 user_id 路由單表 + 分區裁剪雙重加速,歸檔 DROP PARTITION 秒級完成。
分表解決「寫得快、擴得開」,分區解決「刪得快、查得準」,兩者不互斥,而是互補。