MySQL儲存引擎——MERGE

2020-08-13 06:34:11

MERGE儲存引擎把一組MyISAM數據表當做一個邏輯單元來對待,讓我們可以同時對他們進行查詢。構成一個MERGE數據表結構的各成員MyISAM數據表必須具有完全一樣的結構。每一個成員數據表的數據列必須按照同樣的順序定義同樣的名字和型別,索引也必須按照同樣的順序和同樣的方式定義。

假設你有幾個日誌數據表,他們內容分別是這幾年來每一年的日誌記錄項,他們的定義都是下面 下麪這樣,YY代表年份:CREATE TABLE log_YY  

(  

  dt  DATETIME NOT NULL,  

  info VARCHAR(100) NOT NULL,  

  INDEX (dt)  

) ENGINE = MyISAM;  

假設日誌數據表的當前集合包括 log_2004、log_2005、log_2006、log_2007 ,而你可以建立一個如下所示的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);  


ENGINE選項的值必須是MERGE,UNION選項列出了將被收錄在這個MERGE數據表離得各有關數據表。把這個MERGE建立出來後,就可以像對待任何其他數據表那樣查詢它,只是每一次查詢都將同時作用與構成它的每一個成員數據表 。

下面 下麪這個查詢可以讓我們知道上述幾個日誌數據表的數據行的總數:

SELECT COUNT(*) FROM log_merge;  

下面 下麪這個查詢用來確定在這幾年裡每年各有多少日誌記錄項:

SELECT YEAR(dt) AS y, COUNT(*) AS entries FROM log_merge GROUP BY y;  

除了便於同時參照多個數據表而無需發出多條查詢,MERGE數據表還提供了以下一些便利。

MERGE數據表可以用來建立一個尺寸超過各個MyISAM數據表所允許的最大長度邏輯單元

你看一把經過壓縮的數據表包括到MERGE數據表裏。比如說,在某一年結束之後,你應該不會再往相應的日誌檔案裡新增記錄,所以你可以用myisampack工具壓縮它以節省空間,而MERGE數據表仍可以像往常那樣工作

MERGE數據表也支援DELETE 和UPDATE操作。INSERT操作比較麻煩,因爲MySQL需要知道應該把新數據行插入到哪一個成員表裏去。在MERGE數據表的定義裡可以包括一個INSERT_METHOD選項,這個選項的可取值是NO、FIRST、LAST,他們的含義依次是INSERT操作是被禁止的、新數據行將被插入到現在UNION選項裡列出的第一個數據表或最後一個數據表。比如說,以下定義將對log_merge數據表的INSERT操作被當作對log_2007數據表----它是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_2009並讓他有同樣的表結構,然後修改log_merge數據表把log_2009包括進來:

log_2009:  

CREATE TABLE log_2009 LIKE log_2008;  

ALTER TABLE log_merge  

UNION = (log_2004, log_2005, log_2006, log_2007,log_2008,log_2009);  

 

MySQL中merge表儲存引擎用法

在Mysql數據庫中,Merge表有點類似於檢視。mysql的merge引擎型別允許你把許多結構相同的表合併爲一個表。之後,你可以執行查詢,從多個表返回的結果就像從一個表返回的結果一樣。每一個合併的表必須有完全相同表的定義和結構。

Mysql Merge表的優點:

A. 分離靜態的和動態的數據

B. 利用結構接近的的數據來優化查詢

C. 查詢時可以存取更少的數據

D. 更容易維護大數據集

E. 可以通過修改.mrg檔案來修改Merge表,當然也可以用alter進行修改,修改後要通過FLUSH TABLES重新整理表快取,此法可以動態增加減少子表

如果需要把日誌記錄不停的錄入MySQL數據庫,並且每天、每週或者每個月都建立一個 單一的表,而且要製作來自多個表的合計查詢,MERGE表這時會非常有效。然而,這項功能有侷限性。你只能合併MyISAM表而且必須嚴格遵守相同的表定 義的限制。雖然這看起來好像是一個大問題,但是,如果你使用另外一種表型別(例如InnoDB),這種合併可能就不需要.
下面 下麪定義如下幾個表:

基本表:

CREATE TABLE TEST_MERGE_1(
ID INT(5) NOT NULL,
VALUE VARCHAR(100) NOT NULL,
PRIMARY KEY(ID)
)TYPE=MyISAM;

CREATE TABLE TEST_MERGE_2(
ID INT(5) NOT NULL,
VALUE VARCHAR(100) NOT NULL,
PRIMARY KEY(ID))TYPE=MyISAM;

CREATE TABLE TEST_MERGE(
ID INT(5) NOT NULL,
VALUE VARCHAR(100) NOT NULL,
PRIMARY KEY(ID)
) TYPE=MRG_MyISAM INSERT_METHOD=LAST AUTO_INCREMENT=1 UNION=(TEST_MERGE_1,TEST_MERGE_2);

說明:
1. 此表結構必須與基本表完全一致,包括列名、順序。UNION表必須同屬一個DATABASE
2. 此表類似於SQL中的union機制 機製。
3. 基本表型別必須是MyISAM的
4. 可以通過修改.mrg檔案來修改MERGE表,每個基本表的名字佔一行。注意:修改後要通過FLUSH TABLES重新整理表快取。
5. 對基本表的更改可以直接反映在此表上。
6. INSERT_METHOD的取值可以是: 0 不允許插入 FIRST 插入到UNION中的第一個表 LAST 插入到UNION中的最後一個表。(4.0之後可用)
7. 定義在它上面的約束沒有任何作用,約束是由基本表控制的,例如兩個基本表中存在着同樣的一個Key值,那麼在MERGE表中會有兩個一樣的Key值。

注意:
1.如果是通過修改.mrg檔案的方式來修改MERGE表,那麼一定要修改後要通過FLUSH TABLES重新整理表快取,否則修改不會生效。最近犯過一次這樣的錯誤。
2.在數據量、查詢量較大的情況下,不要試圖使用Merge表來達到類似於Oracle的表分割區的功能,會很影響效能。我的感覺是和union幾乎等價。
3.查詢結果及順序與建立Merge表時聯合表的順序有關。
假設有這樣兩條個語句:
INSERT INTO TEST_MERGE_1(ID,VALUE) VALUES(1,'ciray');
INSERT INTO TEST_MERGE_2(ID,VALUE) VALUES(1,'blog.csdn.net/ciray');
然後,這個查詢:
SELECT * FROM TEST_MERGE WHERE ID=1;
將 只會得到一條記錄(1,'ciray'),並不是兩條記錄,也不會是(1,'blog.csdn.net/ciray')。這是因爲ID是 PRIMARY KEY,如果在第一個表中查詢到記錄,則不在後面的表中記錄查。如果ID並沒有定義唯一性約束,則這個查詢會得到兩條記錄。