首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL MERGE 存儲引擎:邏輯分表查詢統一入口、INSERT_METHOD 寫入路由與避坑指南

     編輯:MySQL 資料庫相關知識

核心概念

MERGE 引擎 將多張結構完全相同的 MyISAM 表聚合為一個邏輯表,查詢時自動路由到所有成員表。

前置條件:成員表結構完全一致

  • 列名、類型、順序完全相同
  • 索引定義順序、方式完全相同
  • 引擎必須為 MyISAM

經典場景:按年分表日志聚合查詢

成員表(年分表)


CREATE TABLE log_2004 (dt DATETIME NOT NULL, info VARCHAR(100) NOT NULL, INDEX(dt)) ENGINE=MyISAM;
CREATE TABLE log_2005 (dt DATETIME NOT NULL, info VARCHAR(100) NOT NULL, INDEX(dt)) ENGINE=MyISAM;
CREATE TABLE log_2006 (dt DATETIME NOT NULL, info VARCHAR(100) NOT NULL, INDEX(dt)) ENGINE=MyISAM;
CREATE TABLE log_2007 (dt DATETIME NOT NULL, info VARCHAR(100) NOT NULL, INDEX(dt)) ENGINE=MyISAM;

建立 MERGE 總表


CREATE TABLE log_merge (
    dt DATETIME NOT NULL,
    info VARCHAR(100) NOT NULL,
    INDEX(dt)
) ENGINE=MERGE UNION=(log_2004,log_2005,log_2006,log_2007);

查詢示例:一次 SQL 掃描四張表


-- 總行數
SELECT COUNT(*) FROM log_merge;

-- 按年統計
SELECT YEAR(dt) AS y, COUNT(*) AS entries FROM log_merge GROUP BY y;

-- 範圍查詢
SELECT * FROM log_merge WHERE dt BETWEEN '2005-01-01' AND '2005-12-31';

寫入路由:INSERT_METHOD 參數

值行為適用場景
NO禁止 INSERT(默認)唯讀聚合視圖
FIRST寫入 UNION 列表第一張表熱數據寫最新表
LAST寫入 UNION 列表最後一張表歸檔數據寫最舊表

指定寫入最新分表


CREATE TABLE log_merge (
    dt DATETIME NOT NULL,
    info VARCHAR(100) NOT NULL,
    INDEX(dt)
) ENGINE=MERGE UNION=(log_2004,log_2005,log_2006,log_2007) INSERT_METHOD=LAST;
-- 新數據自動寫入 log_2007

動態增減成員表


-- 新增 2008 年分表
CREATE TABLE log_2008 LIKE log_2007;
ALTER TABLE log_merge UNION=(log_2004,log_2005,log_2006,log_2007,log_2008);

⚠️ 核心避坑:主鍵衝突導致查詢丟數據

MERGE 表成員最好不要定義主鍵!
若兩張成員表存在相同主鍵值,通過 MERGE 表按該主鍵查詢,**只會返回 UNION 列表中第一張表的行**,後續表的同鍵行被隱性忽略。

適用性評估

  • ✅ 歷史歸檔表、日志表、報表聚合、唯讀/追加寫入
  • ❌ 高併發寫入、需要事務、主鍵業務關鍵、InnoDB 表
  • 🔄 現代替代方案:分區表、Spider 引擎、Vitess/ShardingSphere 中間件

總結

MERGE 引擎為「同結構 MyISAM 表聚合查詢」提供零代碼改造的統一入口,但受限於 MyISAM 無事務、表鎖、主鍵衝突等短板,新架構建議優先考慮原生分區表或分庫中間件。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved