一. 什么是MERGE引擎
MERGE存儲引擎把一組MyISAM數據表當做一個邏輯單元來對待,讓我們可以同時對他們進行查詢。
二. 應用場景
如果需要把日志紀錄不停的錄入MySQL數據庫,並且每天、每周或者每個月都創建一個單一的表,而且要時常進行來自多個表的合計查詢,MERGE表這時會非常簡單有效。
三. 舉例
假設有如下兩表
1 CREATE TABLE `t1` ( 2 `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 3 `log` varchar(45) , 4 PRIMARY KEY (`id`) 5 ) ENGINE=MyISAM;
1 CREATE TABLE `t2`( 2 `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 3 `log` varchar(45) , 4 PRIMARY KEY (`id`) 5 ) ENGINE=MyISAM;
假設t1,t2中都有如下記錄
+----+-------+
| id | log |
+----+-------+
| 1 | test1 |
| 2 | test2 |
| 3 | test3 |
+----+-------+
建立MERGE表
1 CREATE TABLE `t` ( 2 `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 3 `log` varchar(45) NOT NULL, 4 PRIMARY KEY (`id`) 5 ) ENGINE=MERGE UNION=(t1, t2) INSERT_METHOD=LAST;
執行select * from t;將會得到如下結果
+----+-------+
| id | log |
+----+-------+
| 1 | test1 |
| 2 | test2 |
| 3 | test3 |
| 1 | test1 |
| 2 | test2 |
| 3 | test3|
+----+-------+
從效果上看,t1,t2的記錄如同在一張表里一樣被羅列了出來。當然,看了這個結果你一定會有一些疑問,在下一節里我們會慢慢解釋。現在我們主要來解釋一下上面MERGE表的建表語句。
1)ENGINE=MERGE
指明使用MERGE引擎,有些同學可能見到過ENGINE=MRG_MyISAM的例子,也是對的,它們是一回事。
2)UNION=(t1, t2)
指明了MERGE表中掛接了些哪表,可以通過alter table的方式修改UNION的值,以實現增刪MERGE表子表的功能。
3)INSERT_METHOD=LAST
INSERT_METHOD指明插入方式,取值可以是:0 不允許插入;FIRST 插入到UNION中的第一個表; LAST 插入到UNION中的最后一個表。
4)MERGE表及構成MERGE數據表結構的各成員數據表必須具有完全一樣的結構。每一個成員數據表的數據列必須按照同樣的順序定義同樣的名字和類型,索引也必須按照同樣的順序和同樣的方式定義。
四. Cookie問答
1)建表時UNION指明的子表如果存在相同主鍵的記錄會怎么樣?
相同主鍵的記錄會同時存在於MERGE中,就像第三節中的例子所示。但如果繼續向MERGE表中插入數據,若數據主鍵已存在則無法插入。換言之,MERGE表只對建表之后的操作負責。
2)若MREGE后存在重復主鍵,按主鍵查詢會是什么結果?
順序查詢,只出現一條查詢記錄即停止。比如第三節中的例子,如果執行
1 select * from t where id=1;
只會得到結果
+----+--------+
| id | log |
+----+--------+
| 1 | test1 |
+----+--------+
3)直接刪除一個子表會出現什么情況,正確刪除的方式是怎樣的?
MERGE表會被破壞,正確方式是用alter table方式先將子表從MERGE表中去除,再刪除子表。
以第三節中的例子為例,執行如下操作
可以從MERGE表中去除t2,這里你可以安全的對t2進行任何操作了。
4)誤刪子表時,如何恢復MERGE表?
誤刪子表時,MERGE表上將無法進行任何操作。
方法1,drop MERGE表,重建。重建時注意在UNION部分去掉誤刪的子表。
方法2,建立MERGE表時,會在數據庫目錄下生成一個.MRG文件,比如設表名為t,則文件名為t.MRG。
文件內容類似:
t1
t2
#INSERT_METHOD=LAST
指明了MGEGE表的子表構成及插入方式。
可以直接修改此文件,去掉誤刪表的表名。然后執行flush tables即可修復MERGE表。
5)MERGE的子表中之前有記錄,且有自增主鍵,則MERGE表創建后,向其插入記錄時主鍵以什么規則自增?
以各表中的AUTO_INCREMENT最大值做為下一次插入記錄的主鍵值。
比如t1的自增ID至6,t2至4,則創建MERGE表后,插入的下一條記錄ID將會是7
6)兩個結構完全相同的但已存在數據的表,是否一定可以合成一個MEREGE表?
從實驗的結果看,不是這樣的,有時創建出的表,無法進行任何操作。
所以,推薦的使用方法是先有一個MERGE表,里面只包含一張表,當一個這個表的的大小增長到一定程度(比如200w)時,創建另一張空表,將其掛入MERGE表,然后繼續插入記錄。
7)刪除MERGE表是否會對子表產生影響?
不會
8)MREGE表的子表的ENGIN是否有要求?
有的,必須是MyISAM表
附:
官方給出的關於MERGE表存在的一些問題
http://dev.mysql.com/doc/refman/5.1/zh/storage-engines.html#merge-table-problems
如果需要把日志紀錄不停的錄入MySQL數據庫,並且每天、每周或者每個月都創建一個單一的表,而且要時常進行來自多個表的合計查詢,MERGE表這時會非常簡單有效。