天天看點

MySQL的分區表

 MySQL從5.1版本開始支援分區的功能。分區是指根據一定的規則,資料庫把一個表分解成多個更小的、更容易管理的部分。就通路資料庫的應用而言,邏輯上隻有一個表或一個索引,但是實際上這個表可能由數十個實體分區對象組成,每個分區都是一個獨立的對象,可以獨自處理,可以作為表的一部分進行處理。分區對應用來說是完全透明的,不影響應用的業務邏輯。

 1、檢視使用的MySQL是否支援分區表。

    5.6.1版本以後使用show plugins;指令檢視

<code>mysql&gt; show plugins;</code>

<code>+</code><code>----------------------------+----------+--------------------+---------+---------+</code>

<code>| </code><code>Name</code>                       <code>| Status   | Type               | Library | License |</code>

<code>| binlog                     | ACTIVE   | STORAGE ENGINE     | </code><code>NULL</code>    <code>| GPL     |</code>

<code>| mysql_native_password      | ACTIVE   | AUTHENTICATION     | </code><code>NULL</code>    <code>| GPL     |</code>

<code>| mysql_old_password         | ACTIVE   | AUTHENTICATION     | </code><code>NULL</code>    <code>| GPL     |</code>

<code>| sha256_password            | ACTIVE   | AUTHENTICATION     | </code><code>NULL</code>    <code>| GPL     |</code>

<code>......</code>

<code>| INNODB_SYS_TABLESPACES     | ACTIVE   | INFORMATION </code><code>SCHEMA</code> <code>| </code><code>NULL</code>    <code>| GPL     |</code>

<code>| INNODB_SYS_DATAFILES       | ACTIVE   | INFORMATION </code><code>SCHEMA</code> <code>| </code><code>NULL</code>    <code>| GPL     |</code>

<code>| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | </code><code>NULL</code>    <code>| GPL     |</code>

<code>| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | </code><code>NULL</code>    <code>| GPL     |</code>

<code>| partition                  | ACTIVE   | STORAGE ENGINE     | </code><code>NULL</code>    <code>| GPL     |</code>

    5.6.1以前的版本使用show variables like '%partition%';指令檢視

<code>mysql&gt; show variables </code><code>like</code> <code>'%partition%'</code><code>;</code>

<code>+</code><code>-------------------+-------+</code>

<code>| Variable_name     | Value |</code>

<code>| have_partitioning | YES   |</code>

 2、分區類型

  MySQL中可用的分區類型主要有以下4種:

RANGE分區:基于一個給定連續區間範圍,把資料配置設定到不同的分區。

LIST分區:類似RANGE分區,差別在于LIST分區是基于枚舉出的值清單分區,RANGE是基于給定的連續區間範圍分區。

HASH分區:基于給定的分區個數,把資料配置設定到不同的分區。

KEY分區:類似于HASH分區。

 RANGE分區、LIST分區、HASH分區都要求分區必須是INT類型,或者通過表達式傳回INT類型,唯一的例外就是分區類型為KEY分區時,可以使用其他類型的列(BLOB或TEXT列類型除外)作為分區鍵。在5.5或以上版本中,已經支援非整數的RANGE和LIST分區了,使用RANGE COLUMNS和LIST COLUMNS分區實作(後面介紹)。無論是哪種MySQL分區類型,要麼分區表上沒有主鍵/唯一鍵,要麼分區表的主鍵/唯一鍵都必須都包含分區鍵。

  2.1、RANGE分區

按照RANGE分區的表是利用取值範圍将資料分成分區,區間要連續并且不能互相重疊,使用VALUES LESS THAN 操作符進行分區定義。

<code>mysql&gt; </code><code>create</code> <code>table</code> <code>emp (</code>

<code>    </code><code>-&gt; id </code><code>int</code> <code>not</code> <code>null</code><code>,</code>

<code>    </code><code>-&gt; ename </code><code>varchar</code><code>(30),</code>

<code>    </code><code>-&gt; hired </code><code>date</code> <code>not</code> <code>null</code> <code>default</code> <code>'2016-01-01'</code><code>,</code>

<code>    </code><code>-&gt; separated </code><code>date</code> <code>not</code> <code>null</code> <code>default</code> <code>'9999-12-31'</code><code>,</code>

<code>    </code><code>-&gt; job </code><code>varchar</code><code>(30) </code><code>not</code> <code>null</code><code>,</code>

<code>    </code><code>-&gt; store_id </code><code>int</code> <code>not</code> <code>null</code><code>)</code>

<code>    </code><code>-&gt; partition </code><code>by</code> <code>range (store_id)</code>

<code>    </code><code>-&gt; (</code>

<code>    </code><code>-&gt; partition p0 </code><code>values</code> <code>less than (10),</code>

<code>    </code><code>-&gt; partition p1 </code><code>values</code> <code>less than (20),</code>

<code>    </code><code>-&gt; partition p2 </code><code>values</code> <code>less than (30)</code>

<code>    </code><code>-&gt; );</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.08 sec)</code>

<code>mysql&gt; show </code><code>create</code> <code>table</code> <code>emp \G;</code>

<code>*************************** 1. row ***************************</code>

<code>       </code><code>Table</code><code>: emp</code>

<code>Create</code> <code>Table</code><code>: </code><code>CREATE</code> <code>TABLE</code> <code>`emp` (</code>

<code>  </code><code>`id` </code><code>int</code><code>(11) </code><code>NOT</code> <code>NULL</code><code>,</code>

<code>  </code><code>`ename` </code><code>varchar</code><code>(30) </code><code>DEFAULT</code> <code>NULL</code><code>,</code>

<code>  </code><code>`hired` </code><code>date</code> <code>NOT</code> <code>NULL</code> <code>DEFAULT</code> <code>'2016-01-01'</code><code>,</code>

<code>  </code><code>`separated` </code><code>date</code> <code>NOT</code> <code>NULL</code> <code>DEFAULT</code> <code>'9999-12-31'</code><code>,</code>

<code>  </code><code>`job` </code><code>varchar</code><code>(30) </code><code>NOT</code> <code>NULL</code><code>,</code>

<code>  </code><code>`store_id` </code><code>int</code><code>(11) </code><code>NOT</code> <code>NULL</code>

<code>) ENGINE=InnoDB </code><code>DEFAULT</code> <code>CHARSET=latin1</code>

<code>/*!50100 PARTITION </code><code>BY</code> <code>RANGE (store_id)</code>

<code>(PARTITION p0 </code><code>VALUES</code> <code>LESS THAN (10) ENGINE = InnoDB,</code>

<code> </code><code>PARTITION p1 </code><code>VALUES</code> <code>LESS THAN (20) ENGINE = InnoDB,</code>

<code> </code><code>PARTITION p2 </code><code>VALUES</code> <code>LESS THAN (30) ENGINE = InnoDB) */</code>

<code>1 row </code><code>in</code> <code>set</code> <code>(0.00 sec)</code>

emp表可以存儲store_id&lt;30的資料,并且根據store_id值選擇不同的分區,如store_id=9則存儲在p0分區,如果store_id=10則存儲在p1分區。如果插入store_id大于30的行會報錯:

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>emp (id,ename,hired,job,store_id) </code><code>values</code><code>(</code><code>'1'</code><code>,</code><code>'zx'</code><code>,</code><code>'2016-01-01'</code><code>,</code><code>'zx'</code><code>,50);</code>

<code>ERROR 1526 (HY000): </code><code>Table</code> <code>has </code><code>no</code> <code>partition </code><code>for</code> <code>value 50</code>

可以在設定分區的時候使用使用VALUES LESS THAN MAXVALUE 子名,該子名提供給所有大于明确指定的最高值的值,MAXVALUES表示最大的可能的整數值。

<code>mysql&gt; </code><code>alter</code> <code>table</code> <code>emp </code><code>add</code> <code>partition (partition p3 </code><code>values</code> <code>less than maxvalue);</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.14 sec)</code>

<code>Records: 0  Duplicates: 0  Warnings: 0</code>

<code>Query OK, 1 row affected (0.02 sec)</code>

MySQL支援在VALUES LESS THAN 子句中使用表達式,比如,以日期作為RANGE分區的分區列:

<code>mysql&gt; </code><code>create</code> <code>table</code> <code>emp_date (</code>

<code>    </code><code>-&gt; partition </code><code>by</code> <code>range (</code><code>YEAR</code><code>(separated))</code>

<code>    </code><code>-&gt; partition p0 </code><code>values</code> <code>less than (2014),</code>

<code>    </code><code>-&gt; partition p1 </code><code>values</code> <code>less than (2015),</code>

<code>    </code><code>-&gt; partition p2 </code><code>values</code> <code>less than (2016)</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.48 sec)</code>

檢視語句的執行計劃

<code>mysql&gt; explain partitions </code><code>select</code> <code>* </code><code>from</code> <code>emp </code><code>where</code> <code>store_id=50\G;</code>

<code>           </code><code>id: 1</code>

<code>  </code><code>select_type: SIMPLE</code>

<code>        </code><code>table</code><code>: emp</code>

<code>   </code><code>partitions: p3</code>

<code>         </code><code>type: </code><code>ALL</code>

<code>possible_keys: </code><code>NULL</code>

<code>          </code><code>key</code><code>: </code><code>NULL</code>

<code>      </code><code>key_len: </code><code>NULL</code>

<code>          </code><code>ref: </code><code>NULL</code>

<code>         </code><code>rows</code><code>: 2</code>

<code>        </code><code>Extra: Using </code><code>where</code>

<code>ERROR: </code>

<code>No</code> <code>query specified</code>

  2.2 LIST分區

  LIST分區是建立離散的值清單告訴資料庫特定的值屬于哪個分區,LIST分區在很多方面類似于RANGE分區,差別在LIST分區是從屬于一個枚舉清單的值的集合,RANGE分區是從屬于一個連續區間值的集合。

  LIST分區通過使用PARTITION BY LIST(expr)子名來實作,expr是某列值或一個基于某列值傳回一個整數值的表達式,然後通過VALUES IN(value_list)的方式來定義分區,其中value_list是一個逗号分隔的整數清單。與RANGE分區不同,LIST分區不必聲明任何特定的順序。

<code>mysql&gt; </code><code>create</code> <code>table</code> <code>expenses(</code>

<code>    </code><code>-&gt; expense_date </code><code>date</code> <code>not</code> <code>null</code><code>,</code>

<code>    </code><code>-&gt; category </code><code>int</code><code>,</code>

<code>    </code><code>-&gt; amount </code><code>decimal</code><code>(10,3))</code>

<code>    </code><code>-&gt; partition </code><code>by</code> <code>list (category)</code>

<code>    </code><code>-&gt; partition p0 </code><code>values</code> <code>in</code> <code>(3,5),</code>

<code>    </code><code>-&gt; partition p1 </code><code>values</code> <code>in</code> <code>(1,10)</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.73 sec)</code>

如果試圖插入的列值(或者分區表達式的反回值)不包含分區值清單中時,那麼INSERT操作會失敗并報錯。

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>expenses(expense_date,category) </code><code>values</code><code>(</code><code>'2016-11-25'</code><code>,2);</code>

<code>ERROR 1526 (HY000): </code><code>Table</code> <code>has </code><code>no</code> <code>partition </code><code>for</code> <code>value 2</code>

  2.3 Columns分區

  Columns分區是在MySQL5.5引入的分區類型,引入Columns分區解決了MySQL5.5版本之前RANGE分區和LIST分區隻支援整數分區,進而導緻需要額外的函數計算等到整數或通過額外的轉換表來轉換為整數再分區的問題。Columns分區可以細分為RANGE Columns和LIST Columns分區,它們都支援整數、日期時間、字元串三大資料類型。

<code>mysql&gt; </code><code>drop</code> <code>table</code> <code>emp_date;</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.06 sec)</code>

<code>    </code><code>-&gt; partition </code><code>by</code> <code>range columns (separated)</code>

<code>    </code><code>-&gt; partition p0 </code><code>values</code> <code>less than (</code><code>'2014-01-01'</code><code>),</code>

<code>    </code><code>-&gt; partition p1 </code><code>values</code> <code>less than (</code><code>'2015-01-01'</code><code>),</code>

<code>    </code><code>-&gt; partition p2 </code><code>values</code> <code>less than (</code><code>'2016-01-01'</code><code>)</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.10 sec)</code>

<code>mysql&gt; </code><code>drop</code> <code>table</code> <code>expenses;</code>

<code>    </code><code>-&gt; category </code><code>varchar</code><code>(30),</code>

<code>    </code><code>-&gt; partition </code><code>by</code> <code>list columns (category)</code>

<code>    </code><code>-&gt; partition p0 </code><code>values</code> <code>in</code> <code>(</code><code>'food'</code><code>,</code><code>'lodging'</code><code>),</code>

<code>    </code><code>-&gt; partition p1 </code><code>values</code> <code>in</code> <code>(</code><code>'flights'</code><code>)</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.13 sec)</code>

對比RANGE分區和LIST分區,Columns分區的亮點除了支援資料類型增加之外,另外一大亮點是Columns分區還支援多列分區。

<code>mysql&gt; </code><code>create</code> <code>table</code> <code>rc3(</code>

<code>    </code><code>-&gt; a </code><code>int</code><code>,</code>

<code>    </code><code>-&gt; b </code><code>int</code><code>)</code>

<code>    </code><code>-&gt; partition </code><code>by</code> <code>range columns (a,b)</code>

<code>    </code><code>-&gt; partition p01 </code><code>values</code> <code>less than (1,10),</code>

<code>    </code><code>-&gt; partition p02 </code><code>values</code> <code>less than (10,10),</code>

<code>    </code><code>-&gt; partition p03 </code><code>values</code> <code>less than (10,20),</code>

<code>    </code><code>-&gt; partition p04 </code><code>values</code> <code>less than (10,maxvalue),</code>

<code>    </code><code>-&gt; partition p05 </code><code>values</code> <code>less than (maxvalue,maxvalue)</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.23 sec)</code>

RANGE Columns 分區鍵的比較是基于元組的比較,也就是基于字段組的比較,這和之前RANGE分區鍵的比較有些差異,比較邏輯為(a&lt;10) or ((a=10)and(b&lt;10))。下面插入幾條測試資料驗證一下。

<code>--插入(0,11)</code>

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>rc3(a,b) </code><code>values</code><code>(0,11);</code>

<code>Query OK, 1 row affected (0.01 sec)</code>

<code>mysql&gt; </code><code>select</code> <code>partition_name part,partition_expression expr,partition_description descr,table_rows</code>

<code>    </code><code>-&gt; </code><code>from</code> <code>information_schema.partitions</code>

<code>    </code><code>-&gt; </code><code>where</code> <code>table_schema=</code><code>schema</code><code>() </code><code>and</code> <code>table_name=</code><code>'rc3'</code><code>;</code>

<code>+</code><code>------+---------+-------------------+------------+</code>

<code>| part | expr    | descr             | table_rows |</code>

<code>| p01  | `a`,`b` | 1,10              |          1 |</code>

<code>| p02  | `a`,`b` | 10,10             |          0 |</code>

<code>| p03  | `a`,`b` | 10,20             |          0 |</code>

<code>| p04  | `a`,`b` | 10,MAXVALUE       |          0 |</code>

<code>| p05  | `a`,`b` | MAXVALUE,MAXVALUE |          0 |</code>

<code>5 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.01 sec)</code>

<code>--插入(1,10)</code>

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>rc3(a,b) </code><code>values</code><code>(1,10);</code>

<code>| p02  | `a`,`b` | 10,10             |          1 |</code>

<code>--插入(12,15)</code>

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>rc3(a,b) </code><code>values</code><code>(12,15);</code>

<code>Query OK, 1 row affected (0.08 sec)</code>

<code>| p05  | `a`,`b` | MAXVALUE,MAXVALUE |          1 |</code>

  2.4 HASH分區

  HASH分區主要用來分散熱點讀,確定資料在預先确定個數的分區中盡可能平均分布。對一個表執行HASH分區時,Mysql會對分區鍵應用一個英散列函數,以此确定資料應當放在N個分區中的哪個。MySQL支援兩種HASH分區:正常HASH分區和線性HASH分區(LINEAR HASH分區)。正常HAS使用的是取模算法,線性HASH分區使用的是一個線性的2的幂的運算法則。

  正常HASH分區使用PARTITION BY HASH(expr) PARTITIONS num子句來實作。exp是某列值或一個基于某列值傳回一個整數值的表達式,num是一個非負整數,表示分割成分區的數量,預設num=1。資料儲存在哪個分區N=MOD(expr,num)。

<code>    </code><code>-&gt; partition </code><code>by</code> <code>hash (store_id) partitions 4;</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.11 sec)</code>

<code>Query OK, 1 row affected (0.04 sec)</code>

<code>mysql&gt; </code><code>select</code> <code>mod(50,4);</code>

<code>+</code><code>-----------+</code>

<code>| mod(50,4) |</code>

<code>|         2 |</code>

<code>1 row </code><code>in</code> <code>set</code> <code>(0.01 sec)</code>

<code>mysql&gt; </code><code>select</code> <code>partition_name part,partition_expression expr,partition_description descr,table_rows </code><code>from</code> <code>information_schema.partitions </code><code>where</code> <code>table_schema=</code><code>schema</code><code>() </code><code>and</code> <code>table_name=</code><code>'emp'</code><code>;</code>

<code>+</code><code>------+----------+-------+------------+</code>

<code>| part | expr     | descr | table_rows |</code>

<code>| p0   | store_id | </code><code>NULL</code>  <code>|          0 |</code>

<code>| p1   | store_id | </code><code>NULL</code>  <code>|          0 |</code>

<code>| p2   | store_id | </code><code>NULL</code>  <code>|          1 |</code>

<code>| p3   | store_id | </code><code>NULL</code>  <code>|          0 |</code>

  正常HASH分區存在的問題,如果新增一個正常HASH分區,原來的取模算法是MOD(exp,4)就需要修改為MOD(exp,5),原來4個分區中的資料大部分都需要通過重新計算新分區,代價太大。為了降低分區處理上的代價,MySQL提供了線性HASH分區,分區函數是一個線性的2的幂的運算法則。

  線性HASH分區和正常HASH分區在文法上的唯一差別是在"PARTITION BY"子句中添加"LINEAR"關鍵字

<code>    </code><code>-&gt; partition </code><code>by</code> <code>linear hash (store_id) partitions 4;</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.89 sec)</code>

  2.5 KEY分區

  按照Key進行分區非常類似于按照HASH分區,隻不過HASH分區允許使用使用者自定義的表達式,而Key分區不允許,需要使用Mysql伺服器提供的HASH函數。Key分區支援使用除BLOB或TEXT類型外的其他類型列作為分區鍵。使用PARTITION BY KEY(expr)子句來建立一個Key分區表,exp是0個或多個字段名我的清單。

<code>    </code><code>-&gt; partition </code><code>by</code> <code>key</code> <code>(job) partitions 4;</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.17 sec)</code>

<code>+</code><code>------+-------+-------+------------+</code>

<code>| part | expr  | descr | table_rows |</code>

<code>| p0   | `job` | </code><code>NULL</code>  <code>|          0 |</code>

<code>| p1   | `job` | </code><code>NULL</code>  <code>|          0 |</code>

<code>| p2   | `job` | </code><code>NULL</code>  <code>|          0 |</code>

<code>| p3   | `job` | </code><code>NULL</code>  <code>|          0 |</code>

<code>4 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.01 sec)</code>

<code>mysql&gt; </code><code>select</code> <code>partition_name part,partition_expression expr,partition_description descr,table_rows </code><code>from</code> <code>information_schema.partitions </code><code>where</code> <code>table_schema=</code><code>schema</code><code>() </code><code>and</code> <code>table_name=</code><code>'emp'</code><code>;                           </code>

<code>| p3   | `job` | </code><code>NULL</code>  <code>|          1 |</code>

<code>4 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.00 sec)</code>

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>emp (id,ename,hired,job,store_id) </code><code>values</code><code>(</code><code>'1'</code><code>,</code><code>'zx'</code><code>,</code><code>'2016-01-01'</code><code>,</code><code>'lx'</code><code>,50);</code>

<code>| p1   | `job` | </code><code>NULL</code>  <code>|          1 |</code>

 可以不指定分區鍵,預設會首先選擇使用主鍵作為分區鍵,沒有主鍵的情況會選擇非空唯一鍵作為分區鍵,沒有主鍵也沒有唯一鍵的情況就不能不指定分區鍵了。Key分區也可以像HASH分區一樣使用LINEAR KEY分區。

  2.6子分區

  子分區(subpartitioning)是分區表中對每個分區的再次分割對被稱為複合分區(composite partitioning)。從5.1版本開始支援通過RANGE或LIST分區了的表再進行子分區,子分區可以使用HASH分區或KEY分區。

<code>mysql&gt; </code><code>CREATE</code> <code>TABLE</code> <code>ts (id </code><code>INT</code><code>, purchased </code><code>DATE</code><code>)</code>

<code>    </code><code>-&gt; PARTITION </code><code>BY</code> <code>RANGE( </code><code>YEAR</code><code>(purchased) )</code>

<code>    </code><code>-&gt; SUBPARTITION </code><code>BY</code> <code>HASH( TO_DAYS(purchased) )</code>

<code>    </code><code>-&gt; SUBPARTITIONS 2 (</code>

<code>    </code><code>-&gt; PARTITION p0 </code><code>VALUES</code> <code>LESS THAN (1990),</code>

<code>    </code><code>-&gt; PARTITION p1 </code><code>VALUES</code> <code>LESS THAN (2000),</code>

<code>    </code><code>-&gt; PARTITION p2 </code><code>VALUES</code> <code>LESS THAN MAXVALUE</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.22 sec)</code>

<code>mysql&gt; </code><code>select</code> <code>partition_name part,subpartition_name subpart,partition_expression expr,partition_description descr,table_rows </code><code>from</code> <code>information_schema.partitions </code><code>where</code> <code>table_schema=</code><code>schema</code><code>() </code><code>and</code> <code>table_name=</code><code>'ts'</code><code>;</code>

<code>+</code><code>------+---------+------------------+----------+------------+</code>

<code>| part | subpart | expr             | descr    | table_rows |</code>

<code>| p0   | p0sp0   |  </code><code>YEAR</code><code>(purchased) | 1990     |          0 |</code>

<code>| p0   | p0sp1   |  </code><code>YEAR</code><code>(purchased) | 1990     |          0 |</code>

<code>| p1   | p1sp0   |  </code><code>YEAR</code><code>(purchased) | 2000     |          0 |</code>

<code>| p1   | p1sp1   |  </code><code>YEAR</code><code>(purchased) | 2000     |          0 |</code>

<code>| p2   | p2sp0   |  </code><code>YEAR</code><code>(purchased) | MAXVALUE |          0 |</code>

<code>| p2   | p2sp1   |  </code><code>YEAR</code><code>(purchased) | MAXVALUE |          0 |</code>

<code>6 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.00 sec)</code>

  2.7 MySQL分區處理NULL值的方式

  MySQL不禁止在分區鍵值上使用NULL,分區鍵可能是一個字段或都一個使用者定義的表達式。一般情況下,MySQL的分區把NULL當作0值或一個最小值進行處理。RANGE分區中,NULL值 會被當作最小值來處理;LIST分區中,NULL值必須出現在枚舉清單中,否則不被接受;HASH/KEY分區中,NULL值被當作0值來處理。

<code>mysql&gt; </code><code>create</code> <code>table</code> <code>tb_range(id </code><code>int</code> <code>,</code><code>name</code> <code>varchar</code><code>(2))</code>

<code>    </code><code>-&gt; partition </code><code>by</code> <code>range(id)</code>

<code>    </code><code>-&gt; partition p0 </code><code>values</code> <code>less than (0),</code>

<code>    </code><code>-&gt; partition p1 </code><code>values</code> <code>less than (100),</code>

<code>    </code><code>-&gt; partition p2 </code><code>values</code> <code>less than maxvalue</code>

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>tb_range </code><code>values</code><code>(</code><code>null</code><code>,</code><code>'a'</code><code>);</code>

<code>mysql&gt; </code><code>select</code> <code>partition_name part,partition_expression expr,partition_description descr,table_rows </code><code>from</code> <code>information_schema.partitions </code><code>where</code> <code>table_schema=</code><code>schema</code><code>() </code><code>and</code> <code>table_name=</code><code>'tb_range'</code><code>; </code>

<code>+</code><code>------+------+----------+------------+</code>

<code>| part | expr | descr    | table_rows |</code>

<code>| p0   | id   | 0        |          1 |</code>

<code>| p1   | id   | 100      |          0 |</code>

<code>| p2   | id   | MAXVALUE |          0 |</code>

<code>3 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.00 sec)</code>

LIST分區處理NULL值示例:

<code>mysql&gt; </code><code>create</code> <code>table</code> <code>tb_list(id </code><code>int</code> <code>,</code><code>name</code> <code>varchar</code><code>(2))</code>

<code>    </code><code>-&gt; partition </code><code>by</code> <code>list(id)</code>

<code>    </code><code>-&gt; partition p0 </code><code>values</code> <code>in</code> <code>(0),</code>

<code>    </code><code>-&gt; partition p1 </code><code>values</code> <code>in</code> <code>(1)</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.09 sec)</code>

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>tb_list </code><code>values</code><code>(</code><code>null</code><code>,</code><code>'a'</code><code>);</code>

<code>ERROR 1526 (HY000): </code><code>Table</code> <code>has </code><code>no</code> <code>partition </code><code>for</code> <code>value </code><code>NULL</code>

<code>mysql&gt; </code><code>alter</code> <code>table</code> <code>tb_list </code><code>add</code> <code>partition(partition p2 </code><code>values</code> <code>in</code> <code>(</code><code>null</code><code>));</code>

<code>mysql&gt; </code><code>select</code> <code>partition_name part,partition_expression expr,partition_description descr,table_rows </code><code>from</code> <code>information_schema.partitions </code><code>where</code> <code>table_schema=</code><code>schema</code><code>() </code><code>and</code> <code>table_name=</code><code>'tb_list'</code><code>;</code>

<code>+</code><code>------+------+-------+------------+</code>

<code>| part | expr | descr | table_rows |</code>

<code>| p0   | id   | 0     |          0 |</code>

<code>| p1   | id   | 1     |          0 |</code>

<code>| p2   | id   | </code><code>NULL</code>  <code>|          1 |</code>

HASH分區處理NULL值示例:

<code>mysql&gt; </code><code>create</code> <code>table</code> <code>tb_hash(id </code><code>int</code> <code>,</code><code>name</code> <code>varchar</code><code>(2))</code>

<code>    </code><code>-&gt; partition </code><code>by</code> <code>hash(id) partitions 2;</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.12 sec)</code>

<code>mysql&gt; </code><code>insert</code> <code>into</code> <code>tb_hash </code><code>values</code><code>(</code><code>null</code><code>,</code><code>'a'</code><code>);</code>

<code>mysql&gt; </code><code>select</code> <code>partition_name part,partition_expression expr,partition_description descr,table_rows </code><code>from</code> <code>information_schema.partitions </code><code>where</code> <code>table_schema=</code><code>schema</code><code>() </code><code>and</code> <code>table_name=</code><code>'tb_hash'</code><code>;</code>

<code>| p0   | id   | </code><code>NULL</code>  <code>|          1 |</code>

<code>| p1   | id   | </code><code>NULL</code>  <code>|          0 |</code>

<code>2 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.00 sec)</code>

參考:《深入淺出MySQL》

官方文檔:http://dev.mysql.com/doc/refman/5.6/en/partitioning.html

     本文轉自hbxztc 51CTO部落格,原文連結:http://blog.51cto.com/hbxztc/1876610,如需轉載請自行聯系原作者