如果願意的話,可以把合併表看成一種較老的、有更多限制的分割槽表,但是它們也有自己的用處,並且能提供一些分割槽表不能提供的功能。
合併表實際是容納真正的表的容器。可以使用特殊的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不會像你期望的那樣工作。
mysql對合併表的實現對效能有一些重要的影響。和其他mysql特性一樣,它在某些條件下效能會更好。下面是關於它的一些注意事項:
1) 合併錶比含有同樣資料的非合併表需要更多的檔案描述符。儘管合併表看上去是乙個表,它實際是逐個開啟了下屬表。這樣的結果就是單個表的快取可以建立許多檔案描述符。因此,即使已經配置了表的快取,讓伺服器執行緒的檔案描述符數量不要超過作業系統的限制,合併表仍然有可能導致超過這一限制。
2) 建立合併表的create語句不會檢查下屬表是否是相容的。如果下屬表的定義有輕微的不一樣,mysql會建立合併表,但是卻無法使用。同樣,如果在建立了乙個有效的合併表之後對某個下屬表進行了改變,它也會無法工作,並且會顯示下面的錯誤資訊:"error 1168(hy000):無法開啟定義不同的下屬表,或者非myisam表,或者不存在的表"。
3)訪問合併表的查詢訪問了每乙個下屬表。這也許會使單行鍵查詢比單個表慢。在合併表中限制下屬表是乙個好主意,尤其是它是聯接中的第二個或以後的表。每次操作訪問的資料越少,那麼訪問每個表的開銷相對於整個操作而言就越重要。下面是一些如何使用合併表的注意事項:
4)範圍查詢受訪問所有下屬表的開銷的影響小於單個查詢。
對索引表的表掃瞄和對單個表一樣快。
一旦唯一鍵和主鍵查詢成功,它們就立即停止。在這種情況下,伺服器會挨個訪問下屬表,一旦查詢到了值,就不會再查詢更多的表。
下屬表讀取的順序和creat table語句中定義的一致。如果經常需要按照特定的順序取得資料,可以利用這種特性使合併排序操作更快。
合併表在處理資料方面既有積極的一面,也有消極的一面。
1) 經典的例子就是日誌記錄。日誌是只追加的,所以可以每天用乙個表。每天建立新的表並把它加入到合併表中。也可以把以前的表從合併表中移除掉,把它轉化為壓縮的myisam表,再把它們加回到合併表中。
2) 日誌追加這並不是合併表的唯一用途。它們通常都被用於資料倉儲程式,因為它的另乙個長處就是管理大量的資料。在實際中不太可能管理乙個tb級別的表,但是如果是由單個50gb的表組成的合併表,任務就會簡單很多。
當管理極其巨大的資料庫時,考慮的絕不僅僅是常規操作。還要考慮崩潰與恢復。使用小表是很好的主意。檢查和修復一系列的小表比起乙個大表要快得多,尤其是大表和記憶體不匹配的時候。還可以並行地檢查和修復多個小表。
資料倉儲中另外乙個顧慮就是如何清理掉老的資料。對巨型表使用delete語句最佳狀況下效率不高,而在最壞情況下則是一場災難。但是更改合併表的定義是很簡單的,可以使用drop table命令刪除老的資料。這可以輕易地實現自動化。
3) 合併表並非只對日誌和大量資料有效。它可以方便地按需建立繁忙的表。建立和刪除合併表的代價是很低的。索引可以像對檢視使用union all命令那樣使用合併表。但它的開銷更低,因為伺服器不會把結果放到臨時表中然後再傳遞給客戶端。這使得它對於報告和倉庫化資料非常有用。例如,要建立乙個每晚都會執行的任務,它會把昨天的資料和8天前、15天前、以及之前的每一周的資料進行合併。使用合併表就可以建立無須修改的查詢,並且自動地訪問合適的資料。甚至還可以建立臨時合併表,這是檢視無法做到的。
因為合併表沒有隱藏下屬的myisam表,所以它提供了一些分割槽表無法提供的特性:
乙個myisam表可以包含很多合併表。
可以通過拷貝.frm、.myi、.myd檔案在伺服器之間拷貝下屬表。
可以輕易地把更多的表新增到合併表中。這只需要建立乙個新錶並且更改合併定義即可。
可以建立只包含想要的資料的臨時合併表,例如某個特定時間段的資料。這是分割槽表無法做到的。
如果想對某個表進行備份、恢復、更改、修復,或者其他的操作,可以把它從合併表中移除,完成所有的工作之後再把它加回來。
可以使用myisampack壓縮某些或所有的下屬表。
分割槽表正好相反,mysql隱藏了分割槽表的分割槽,並只能通過分割槽表訪問所有的分割槽
MySQL高階特性之分割槽表
對於使用者而言,分割槽表是乙個獨立的邏輯表,但是在底層由多個物理子表組成。實現分割槽的 實際上是對一組底層表的控制代碼物件的封裝,對分割槽表的請求都會通過控制代碼物件轉化成對儲存引擎的介面呼叫 mysql在建立表的時候可以通過使用partition by子句定義每個分割槽存放的資料。在執行查詢的時候...
mysql 高階特性的簡單入門
首先我們需要了解一下mysql的三大正規化 定義正規化 英文名稱是 normal form,它是英國人 e.f.codd 關聯式資料庫的老祖宗 在上個世紀70年代提出關聯式資料庫模型後總結出來的,正規化是關聯式資料庫理論的基礎,也是我們在設計資料庫結構過程中所要遵循的規則和指導方法。目前有跡可尋的共...
Mysql臨時表特性 解析Mysql臨時表及特點
臨時表是當連線沒有斷開時存在,一旦斷開就不會存在,臨時表的資料和結構都在記憶體中,可以做個測驗,你建立乙個臨時表,但是到響應的資料目錄下並不會找到.frm檔案 mysql create temporary table tmp table name varchar 10 not null,value ...