MySQL高級特性-合併表

               

1. Merge Tables

        如果願意的話,可以把合併表看成一種較老的、有更多限制的分區表,但是它們也有自己的用處,並且能提供一些分區表不能提供的功能。

合併表實際是容納真正的表的容器。可以使用特殊的UNION語法來CREATE TABLE。下面是一個合併表的例子:

mysql> CREATE TABLE t1(a INT NOT NULL PRIMARY KEY)ENGINE=MyISAM;  mysql> CREATE TABLE t2(a INT NOT NULL PRIMARY KEY)ENGINE=MyISAM;  mysql> INSERT INTO t1(a) VALUES(1),(2); mysql> INSERT INTO t2(a) VALUES(1),(2);  mysql> CREATE TABLE mrg(a INT NOT NULL PRIMARY KEY)    ENGINE=MERGE UNION=(t1, t2) INSERT_METHOD=LAST;  mysql> SELECT a FROM mrg;  
+------+ 
  |  a    |  
+------+  
  |   1  |
  |   1  |
  |   2  | 
  |   2  |
 +------+ 

       注意到合併表包含的表列的數量和類型都是一樣的,並且合併表上的索引也會在下屬表上存在。這是創建合併表的要求。也要注意到在每個表的獨有列上有主鍵,這會導致合併表有重複的行。這是合併表的一個侷限:合併表內的每個錶行爲都很正常,但是它不會對下面的所有表進行強制約束。

INSERT_METHOD=LAST

 指令告訴MySQL把所有的INSERT語句都發送到合併表的最後一個表上。定義FIRST或LAST是控制插入數據位置的唯一方式(但是也可以直接插入到下屬表中)。

分區表可以更多地控制數據存放的位置。

下面的INSERT語句對合並表和下屬表都可見:

mysql> INSERT INTO mrg(a) VALUES(3);  mysql> SELECT a FROM t2; 
 +---+  
  | a | 
 +---+ 
  | 1 | 
  | 2 |
  | 3 | 
 +---+ 

合併表還有其他有趣的特性和限制,比如刪除合併表或它的某個下屬表。刪除合併表讓所有的"子表"都變得不可訪問,但是刪除其中的某個子表有不同的影響,它的行爲和操作系統有關。例如,在GNU/Linux上,子表的文件描述符還保持開啓的狀態,並且表還繼續存在,但是隻能從合併表中訪問。

mysql> DROP TABLE t1, t2;  mysql> SELECT a FROM mrg; 
 +------+ 
  | a     | 
 +------+ 
  |     1 | 
  |     1 |  
  |     2 |
  |     2 |
  |     3 | 
 +------+ 

還有一些另外的侷限性和特殊行爲。最好的辦法是閱讀手冊,但是在這兒要說的是REPLACE並不能在所有的合併表上工作,並且AUTO_INCREMENT不會像你期望的那樣工作。

2. 合併表對性能的影響

        MySQL對合並表的實現對性能有一些重要的影響。和其他MySQL特性一樣,它在某些條件下性能會更好。下面是關於它的一些注意事項:

       1) 合併表比含有同樣數據的非合併表需要更多的文件描述符。儘管合併表看上去是一個表,它實際是逐個打開了下屬表。這樣的結果就是單個表的緩存可以創建許多文件描述符。因此,即使已經配置了表的緩存,讓服務器線程的文件描述符數量不要超過操作系統的限制,合併表仍然有可能導致超過這一限制。

        2) 創建合併表的CREATE語句不會檢查下屬表是否是兼容的。如果下屬表的定義有輕微的不一樣,MySQL會創建合併表,但是卻無法使用。同樣,如果在創建了一個有效的合併表之後對某個下屬表進行了改變,它也會無法工作,並且會顯示下面的錯誤信息:"ERROR 1168(HY000):無法打開定義不同的下屬表,或者非MyISAM表,或者不存在的表"。

       3)訪問合併表的查詢訪問了每一個下屬表。這也許會使單行鍵查找比單個錶慢。在合併表中限制下屬表是一個好主意,尤其是它是聯接中的第二個或以後的表。每次操作訪問的數據越少,那麼訪問每個表的開銷相對於整個操作而言就越重要。下面是一些如何使用合併表的注意事項:

       4)範圍查找受訪問所有下屬表的開銷的影響小於單個查找。

      對索引表的表掃描和對單個表一樣快。

       一旦唯一鍵和主鍵查詢成功,它們就立即停止。在這種情況下,服務器會挨個訪問下屬表,一旦查找到了值,就不會再查找更多的表。

下屬表讀取的順序和CREAT TABLE語句中定義的一致。如果經常需要按照特定的順序取得數據,可以利用這種特性使合併排序操作更快。

3. 合併表的長處

     合併表在處理數據方面既有積極的一面,也有消極的一面。

      1) 經典的例子就是日誌記錄。日誌是隻追加的,所以可以每天用一個表。每天創建新的表並把它加入到合併表中。也可以把以前的表從合併表中移除掉,把它轉化爲壓縮的MyISAM表,再把它們加回到合併表中。

      2) 日誌追加這並不是合併表的唯一用途。它們通常都被用於數據倉庫程序,因爲它的另一個長處就是管理大量的數據。在實際中不太可能管理一個TB級別的表,但是如果是由單個50GB的表組成的合併表,任務就會簡單很多。

       當管理極其巨大的數據庫時,考慮的絕不僅僅是常規操作。還要考慮崩潰與恢復。使用小表是很好的主意。檢查和修復一系列的小表比起一個大表要快得多,尤其是大表和內存不匹配的時候。還可以並行地檢查和修復多個小表。

       數據倉庫中另外一個顧慮就是如何清理掉老的數據。對巨型表使用DELETE語句最佳狀況下效率不高,而在最壞情況下則是一場災難。但是更改合併表的定義是很簡單的,可以使用DROP TABLE命令刪除老的數據。這可以輕易地實現自動化。

     3) 合併表並非只對日誌和大量數據有效。它可以方便地按需創建繁忙的表。創建和刪除合併表的代價是很低的。索引可以像對視圖使用UNION ALL命令那樣使用合併表。但它的開銷更低,因爲服務器不會把結果放到臨時表中然後再傳遞給客戶端。這使得它對於報告和倉庫化數據非常有用。例如,要創建一個每晚都會運行的任務,它會把昨天的數據和8天前、15天前、以及之前的每一週的數據進行合併。使用合併表就可以創建無須修改的查詢,並且自動地訪問合適的數據。甚至還可以創建臨時合併表,這是視圖無法做到的。

因爲合併表沒有隱藏下屬的MyISAM表,所以它提供了一些分區表無法提供的特性:

一個MyISAM表可以包含很多合併表。

可以通過拷貝.frm、.MYI、.MYD文件在服務器之間拷貝下屬表。

可以輕易地把更多的表添加到合併表中。這只需要創建一個新表並且更改合併定義即可。

可以創建只包含想要的數據的臨時合併表,例如某個特定時間段的數據。這是分區表無法做到的。

如果想對某個表進行備份、恢復、更改、修復,或者其他的操作,可以把它從合併表中移除,完成所有的工作之後再把它加回來。

可以使用myisampack壓縮某些或所有的下屬表。

分區表正好相反,MySQL隱藏了分區表的分區,並只能通過分區表訪問所有的分區


           

再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章