




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、.第18章:分區(qū)目錄18.1. MySQL中的分區(qū)概述18.2. 分區(qū)類型18.2.1. RANGE分區(qū)18.2.2. LIST分區(qū)18.2.3. HASH分區(qū)18.2.4. KEY分區(qū)18.2.5. 子分區(qū)18.2.6. MySQL分區(qū)處理NULL值的方式18.3. 分區(qū)管理18.3.1. RANGE和LIST分區(qū)的管理18.3.2. HASH和KEY分區(qū)的管理18.3.3. 分區(qū)維護18.3.4. 獲取關于分區(qū)的信息本章討論MySQL 5.1.中實現的分區(qū)。關于分區(qū)和分區(qū)概念的介紹可以在18.1節(jié),“MySQL中的分區(qū)概述”中找到。MySQL 5.1 支持哪幾種類型的分區(qū),在18.2節(jié),“
2、分區(qū)類型” 中討論。關于子分區(qū)在18.2.5節(jié),“子分區(qū)” 中討論。現有分區(qū)表中分區(qū)的增加、刪除和修改的方法在18.3節(jié),“分區(qū)管理” 中介紹。 和分區(qū)表一同使用的表維護命令在18.3.3節(jié),“分區(qū)維護” 中介紹。 請注意:MySQL 5.1中的分區(qū)實現仍然很新(pre-alpha品質),此時還不是可生產的(not production-ready)。 同樣,許多也適用于本章:在這里描述的一些功能還沒有實際上實現(分區(qū)維護和重新分區(qū)命令),其他的可能還沒有完全如所描述的那樣實現(例如, 用于分區(qū)的數據目錄(DATA DIRECTORY)和索引目錄(INDEX DIRECTORY)選項受到Bug
3、 #13520) 不利的影響). 我們已經設法在本章中標出這些差異。在提出缺陷報告前,我們鼓勵參考下面的一些資源:MySQL 分區(qū)論壇 這是一個為對MySQL分區(qū)技術感興趣或用MySQL分區(qū)技術做試驗提供的官方討論論壇。來自MySQL 的開發(fā)者和其他的人,會在上面發(fā)表和更新有關的材料。它由分區(qū)開發(fā)和文獻團隊的成員負責監(jiān)控。 分區(qū)缺陷報告 已經歸檔在缺陷系統(tǒng)中的、所有分區(qū)缺陷的一個列表,而無論這些缺陷的年限、嚴重性或當前的狀態(tài)如何。根據許多規(guī)則可以對這些缺陷進行篩選,或者可以從MySQL缺陷系統(tǒng)主頁開始,然后查找你特別感興趣的缺陷。Mikael Ronstr?m's Blog MySQL
4、分區(qū)體系結構和領先的開發(fā)者Mikael Ronstr?m 經常在這里貼關于他研究MySQL 分區(qū)和MySQL簇的文章。 PlanetMySQL 一個MySQL 新聞網站,它以匯集MySQL相關的網誌為特點,那些使用我的MySQL的人應該對此有興趣。我們鼓勵查看那些研究MySQL分區(qū)的人的網誌鏈接,或者把你自己的網誌加到這些新聞報道中。MySQL 5.1的二進制版本目前還不可用;但是,可以從BitKeeper知識庫中獲得源碼。要激活分區(qū),需要使用-with-分區(qū)選項編譯服務器。關于建立MySQL 的更多信息,請參見2.8節(jié),“使用源碼分發(fā)版安裝MySQL”。如果在編譯一個激活分區(qū)的MySQL 5
5、.1創(chuàng)建中碰到問題,可以在MySQL分區(qū)論壇中查找解決辦法,如果在論壇中已經貼出的文章中沒有找到問題的解決辦法,可以在上面尋找?guī)椭?8.1. MySQL中的分區(qū)概述本節(jié)提供了關于MySQL 5.1.分區(qū)在概念上的概述。 SQL標準在數據存儲的物理方面沒有提供太多的指南。SQL語言的使用獨立于它所使用的任何數據結構或圖表、表、行或列下的介質。但是,大部分高級數據庫管理系統(tǒng)已經開發(fā)了一些根據文件系統(tǒng)、硬件或者這兩者來確定將要用于存儲特定數據塊物理位置的方法。在MySQL中,InnoDB存儲引擎長期支持表空間的概念,并且MySQL服務器甚至在分區(qū)引入之前,就能配置為存儲不同的數據庫使用不同的物理路
6、徑(關于如何配置的解釋,請參見7.6.1節(jié),“使用符號鏈接”)。 分區(qū)又把這個概念推進了一步,它允許根據可以設置為任意大小的規(guī)則,跨文件系統(tǒng)分配單個表的多個部分。實際上,表的不同部分在不同的位置被存儲為單獨的表。用戶所選擇的、實現數據分割的規(guī)則被稱為分區(qū)函數,這在MySQL中它可以是模數,或者是簡單的匹配一個連續(xù)的數值區(qū)間或數值列表,或者是一個內部HASH函數,或一個線性HASH函數。函數根據用戶指定的分區(qū)類型來選擇,把用戶提供的表達式的值作為參數。該表達式可以是一個整數列值,或一個作用在一個或多個列值上并返回一個整數的函數。這個表達式的值傳遞給分區(qū)函數,分區(qū)函數返回一個表示那個特定記錄應該保
7、存在哪個分區(qū)的序號。這個函數不能是常數,也不能是任意數。它不能包含任何查詢,但是實際上可以使用MySQL 中任何可用的SQL表達式,只要該表達式返回一個小于MAXVALUE(最大可能的正整數)的正數值。分區(qū)函數的例子可以在本章后面關于分區(qū)類型的討論中找到 (請參見18.2節(jié),“分區(qū)類型” ),也可在13.1.5節(jié),“CREATE TABLE語法”的分區(qū)語法描述中找到。 當二進制碼變成可用時(也就是說,5.1 -max 二進制碼將通過-with-partition 建立),分區(qū)支持就將包含在MySQL 5.1的-max 版本中。如果MySQL二進制碼是使用分區(qū)支持建立的,那么激活它不需要任何其他
8、的東西 (例如,在f 文件中,不需要特殊的條目)??梢酝ㄟ^使用SHOW VARIABLES命令來確定MySQL是否支持分區(qū),例如:mysql> SHOW VARIABLES LIKE '%partition%' +-+-+| Variable_name | Value |+-+-+| have_partition_engine | YES |+-+-+1 row in set (0.00 sec)在如上列出的一個正確的SHOW VARIABLES 命令所產生的輸出中,如果沒有看到變量have_partition_engine的值為YES,那么MySQL的版本就不支持分區(qū)。
9、(注意:在顯示任何有關分區(qū)支持信息的命令SHOW ENGINES的輸出中,不會給出任何信息;必須使用SHOW VARIABLES命令來做出這個判斷)。對于創(chuàng)建了分區(qū)的表,可以使用你的MySQL 服務器所支持的任何存儲引擎;MySQL 分區(qū)引擎在一個單獨的層中運行,并且可以和任何這樣的層進行相互作用。在MySQL 5.1版中,同一個分區(qū)表的所有分區(qū)必須使用同一個存儲引擎;例如,不能對一個分區(qū)使用MyISAM,而對另一個使用InnoDB。但是,這并不妨礙在同一個 MySQL 服務器中,甚至在同一個數據庫中,對于不同的分區(qū)表使用不同的存儲引擎。 要為某個分區(qū)表配置一個專門的存儲引擎,必須且只能使用S
10、TORAGE ENGINE 選項,這如同為非分區(qū)表配置存儲引擎一樣。但是,必須記住STORAGE ENGINE(和其他的表選項)必須列在用在CREATE TABLE語句中的其他任何分區(qū)選項之前。下面的例子給出了怎樣創(chuàng)建一個通過HASH分成6個分區(qū)、使用InnoDB存儲引擎的表:CREATE TABLE ti (id INT, amount DECIMAL(7,2), tr_date DATE) ENGINE=INNODB PARTITION BY HASH(MONTH(tr_date) PARTITIONS 6;(注釋:每個PARTITION 子句可以包含一個 STORAGE ENGINE 選
11、項,但是在MySQL 5.1版本中,這沒有作用)。 創(chuàng)建分區(qū)的臨時表也是可能的;但是,這種表的生命周期只有當前MySQL 的會話的時間那么長。對于非分區(qū)的臨時表,這也是一樣的。 注釋:分區(qū)適用于一個表的所有數據和索引;不能只對數據分區(qū)而不對索引分區(qū),反之亦然,同時也不能只對表的一部分進行分區(qū)??梢酝ㄟ^使用用來創(chuàng)建分區(qū)表的CREATE TABLE語句的PARTITION子句的DATA DIRECTORY(數據路徑)和INDEX DIRECTORY(索引路徑)選項,為每個分區(qū)的數據和索引指定特定的路徑。此外,MAX_ROWS和MIN_ROWS選項可以用來設定最大和最小的行數,它們可以各自保存在每個
12、分區(qū)里。關于這些選項的更多信息,請參見18.3節(jié),“分區(qū)管理”。注釋:這個特殊的功能由于Bug #13250的原因,目前還不能實用。在第一個5.1二進制版本投入使用時,我們應該已經把這個問題解決了。分區(qū)的一些優(yōu)點包括: · 與單個磁盤或文件系統(tǒng)分區(qū)相比,可以存儲更多的數據。 · 對于那些已經失去保存意義的數據,通??梢酝ㄟ^刪除與那些數據有關的分區(qū),很容易地刪除那些數據。相反地,在某些情況下,添加新數據的過程又可以通過為那些新數據專門增加一個新的分區(qū),來很方便地實現。通常和分區(qū)有關的其他優(yōu)點包括下面列出的這些。MySQL 分區(qū)中的這些功能目前還沒有實現,但是在我們的優(yōu)先級列表
13、中,具有高的優(yōu)先級;我們希望在5.1的生產版本中,能包括這些功能。· 一些查詢可以得到極大的優(yōu)化,這主要是借助于滿足一個給定WHERE 語句的數據可以只保存在一個或多個分區(qū)內,這樣在查找時就不用查找其他剩余的分區(qū)。因為分區(qū)可以在創(chuàng)建了分區(qū)表后進行修改,所以在第一次配置分區(qū)方案時還不曾這么做時,可以重新組織數據,來提高那些常用查詢的效率。 · 涉及到例如SUM() 和 COUNT()這樣聚合函數的查詢,可以很容易地進行并行處理。這種查詢的一個簡單例子如 “SELECT salesperson_id, COUNT(orders) as order_total FROM sale
14、s GROUP BY salesperson_id;”。通過“并行”, 這意味著該查詢可以在每個分區(qū)上同時進行,最終結果只需通過總計所有分區(qū)得到的結果。 · 通過跨多個磁盤來分散數據查詢,來獲得更大的查詢吞吐量。 要經常檢查本頁和本章,因為它將隨MySQL 5.1后續(xù)的分區(qū)進展而更新。 18.2. 分區(qū)類型18.2.1. RANGE分區(qū)18.2.2. LIST分區(qū)18.2.3. HASH分區(qū)18.2.4. KEY分區(qū)18.2.5. 子分區(qū)18.2.6. MySQL分區(qū)處理NULL值的方式本節(jié)討論在MySQL 5.1中可用的分區(qū)類型。這些類型包括: · RANGE 分區(qū):基于
15、屬于一個給定連續(xù)區(qū)間的列值,把多行分配給分區(qū)。參見18.2.1節(jié),“RANGE分區(qū)”。 · LIST 分區(qū):類似于按RANGE分區(qū),區(qū)別在于LIST分區(qū)是基于列值匹配一個離散值集合中的某個值來進行選擇。參見18.2.2節(jié),“LIST分區(qū)”。 · HASH分區(qū):基于用戶定義的表達式的返回值來進行選擇的分區(qū),該表達式使用將要插入到表中的這些行的列值進行計算。這個函數可以包含MySQL 中有效的、產生非負整數值的任何表達式。參見18.2.3節(jié),“HASH分區(qū)”。 · KEY 分區(qū):類似于按HASH分區(qū),區(qū)別在于KEY分區(qū)只支持計算一列或多列,且MySQL 服務器提供其自
16、身的哈希函數。必須有一列或多列包含整數值。參見18.2.4節(jié),“KEY分區(qū)”。 無論使用何種類型的分區(qū),分區(qū)總是在創(chuàng)建時就自動的順序編號,且從0開始記錄,記住這一點非常重要。當有一新行插入到一個分區(qū)表中時,就是使用這些分區(qū)編號來識別正確的分區(qū)。例如,如果你的表使用4個分區(qū),那么這些分區(qū)就編號為0, 1, 2, 和3。對于RANGE和LIST分區(qū)類型,確認每個分區(qū)編號都定義了一個分區(qū),很有必要。對HASH分區(qū),使用的用戶函數必須返回一個大于0的整數值。對于KEY分區(qū),這個問題通過MySQL服務器內部使用的 哈希函數自動進行處理。 分區(qū)的名字基本上遵循其他MySQL 標識符應當遵循的原則,例如用于
17、表和數據庫名字的標識符。但是應當注意,分區(qū)的名字是不區(qū)分大小寫的。例如,下面的CREATE TABLE語句將會產生如下的錯誤: mysql> CREATE TABLE t2 (val INT) -> PARTITION BY LIST(val)( -> PARTITION mypart VALUES IN (1,3,5), -> PARTITION MyPart VALUES IN (2,4,6) -> );錯誤1488 (HY000): 表的所有分區(qū)必須有唯一的名字。這是因為MySQL認為分區(qū)名字mypart和MyPart沒有區(qū)別。 注釋:在下面的章節(jié)中,我們沒
18、有必要提供可以用來創(chuàng)建每種分區(qū)類型語法的所有可能形式,這些信息可以在13.1.5節(jié),“CREATE TABLE語法” 中找到。18.2.1. RANGE分區(qū)按照RANGE分區(qū)的表是通過如下一種方式進行分區(qū)的,每個分區(qū)包含那些分區(qū)表達式的值位于一個給定的連續(xù)區(qū)間內的行。這些區(qū)間要連續(xù)且不能相互重疊,使用VALUES LESS THAN操作符來進行定義。在下面的幾個例子中,假定你創(chuàng)建了一個如下的一個表,該表保存有20家音像店的職員記錄,這20家音像店的編號從1到20。CREATE TABLE employees ( id INT NOT NULL, fname VARCHAR(30), lname
19、 VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01', separated DATE NOT NULL DEFAULT '9999-12-31', job_code INT NOT NULL, store_id INT NOT NULL);根據你的需要,這個表可以有多種方式來按照區(qū)間進行分區(qū)。一種方式是使用store_id 列。例如,你可能決定通過添加一個PARTITION BY RANGE子句把這個表分割成4個區(qū)間,如下所示: CREATE TABLE employees ( id INT NOT NUL
20、L, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01', separated DATE NOT NULL DEFAULT '9999-12-31', job_code INT NOT NULL, store_id INT NOT NULL)PARTITION BY RANGE (store_id) ( PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11), PARTITI
21、ON p2 VALUES LESS THAN (16), PARTITION p3 VALUES LESS THAN (21);按照這種分區(qū)方案,在商店1到5工作的雇員相對應的所有行被保存在分區(qū)P0中,商店6到10的雇員保存在P1中,依次類推。注意,每個分區(qū)都是按順序進行定義,從最低到最高。這是PARTITION BY RANGE 語法的要求;在這點上,它類似于C或Java中的“switch . case”語句。 對于包含數據(72, 'Michael', 'Widenius', '1998-06-25', NULL, 13)的一個新行,可以很容
22、易地確定它將插入到p2分區(qū)中,但是如果增加了一個編號為第21的商店,將會發(fā)生什么呢?在這種方案下,由于沒有規(guī)則把store_id大于20的商店包含在內,服務器將不知道把該行保存在何處,將會導致錯誤。 要避免這種錯誤,可以通過在CREATE TABLE語句中使用一個“catchall” VALUES LESS THAN子句,該子句提供給所有大于明確指定的最高值的值:CREATE TABLE employees ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970
23、-01-01', separated DATE NOT NULL DEFAULT '9999-12-31', job_code INT NOT NULL, store_id INT NOT NULL)PARTITION BY RANGE (store_id) ( PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11), PARTITION p2 VALUES LESS THAN (16), PARTITION p3 VALUES LESS THAN MAXVALUE);MAXVALUE
24、表示最大的可能的整數值?,F在,store_id 列值大于或等于16(定義了的最高值)的所有行都將保存在分區(qū)p3中。在將來的某個時候,當商店數已經增長到25, 30, 或更多 ,可以使用ALTER TABLE語句為商店21-25, 26-30,等等增加新的分區(qū) (關于如何實現的詳細信息參見18.3節(jié),“分區(qū)管理” )。在幾乎一樣的結構中,你還可以基于雇員的工作代碼來分割表,也就是說,基于job_code 列值的連續(xù)區(qū)間。例如假定2位數字的工作代碼用來表示普通(店內的)工人,三個數字代碼表示辦公室和支持人員,四個數字代碼表示管理層,你可以使用下面的語句創(chuàng)建該分區(qū)表:CREATE TABLE emp
25、loyees ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01', separated DATE NOT NULL DEFAULT '9999-12-31', job_code INT NOT NULL, store_id INT NOT NULL)PARTITION BY RANGE (job_code) ( PARTITION p0 VALUES LESS THAN (100), PARTITION p1 VALUE
26、S LESS THAN (1000), PARTITION p2 VALUES LESS THAN (10000);在這個例子中, 店內工人相關的所有行將保存在分區(qū)p0中,辦公室和支持人員相關的所有行保存在分區(qū)p1中,管理層相關的所有行保存在分區(qū)p2中。 在VALUES LESS THAN 子句中使用一個表達式也是可能的。這里最值得注意的限制是MySQL 必須能夠計算表達式的返回值作為LESS THAN (<)比較的一部分;因此,表達式的值不能為NULL 。由于這個原因,雇員表的hired, separated, job_code,和store_id列已經被定義為非空(NOT NULL)
27、。 除了可以根據商店編號分割表數據外,你還可以使用一個基于兩個DATE (日期)中的一個的表達式來分割表數據。例如,假定你想基于每個雇員離開公司的年份來分割表,也就是說,YEAR(separated)的值。實現這種分區(qū)模式的CREATE TABLE 語句的一個例子如下所示:CREATE TABLE employees ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01', separated DATE NOT NULL DEFAULT &
28、#39;9999-12-31', job_code INT, store_id INT)PARTITION BY RANGE (YEAR(separated) ( PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1996), PARTITION p2 VALUES LESS THAN (2001), PARTITION p3 VALUES LESS THAN MAXVALUE);在這個方案中,在1991年前雇傭的所有雇員的記錄保存在分區(qū)p0中,1991年到1995年期間雇傭的所有雇員的記錄保存在分
29、區(qū)p1中, 1996年到2000年期間雇傭的所有雇員的記錄保存在分區(qū)p2中,2000年后雇傭的所有工人的信息保存在p3中。 RANGE分區(qū)在如下場合特別有用:· 當需要刪除“舊的”數據時。如果你使用上面最近的那個例子給出的分區(qū)方案,你只需簡單地使用 “ALTER TABLE employees DROP PARTITION p0;”來刪除所有在1991年前就已經停止工作的雇員相對應的所有行。(更多信息請參見13.1.2節(jié),“ALTER TABLE語法” 和 18.3節(jié),“分區(qū)管理”)。對于有大量行的表,這比運行一個如“DELETE FROM employees WHERE YEAR(
30、separated) <= 1990;”這樣的一個DELETE查詢要有效得多。· 想要使用一個包含有日期或時間值,或包含有從一些其他級數開始增長的值的列。 · 經常運行直接依賴于用于分割表的列的查詢。例如,當執(zhí)行一個如“SELECT COUNT(*) FROM employees WHERE YEAR(separated) = 2000 GROUP BY store_id;”這樣的查詢時,MySQL可以很迅速地確定只有分區(qū)p2需要掃描,這是因為余下的分區(qū)不可能包含有符合該WHERE子句的任何記錄。注釋:這種優(yōu)化還沒有在MySQL 5.1源程序中啟用,但是,有關工作正在
31、進行中。18.2.2. LIST分區(qū)MySQL中的LIST分區(qū)在很多方面類似于RANGE分區(qū)。和按照RANGE分區(qū)一樣,每個分區(qū)必須明確定義。它們的主要區(qū)別在于,LIST分區(qū)中每個分區(qū)的定義和選擇是基于某列的值從屬于一個值列表集中的一個值,而RANGE分區(qū)是從屬于一個連續(xù)區(qū)間值的集合。LIST分區(qū)通過使用“PARTITION BY LIST(expr)”來實現,其中“expr” 是某列值或一個基于某個列值、并返回一個整數值的表達式,然后通過“VALUES IN (value_list)”的方式來定義每個分區(qū),其中“value_list”是一個通過逗號分隔的整數列表。注釋:在MySQL 5.1中
32、,當使用LIST分區(qū)時,有可能只能匹配整數列表。 不像按照RANGE定義分區(qū)的情形,LIST分區(qū)不必聲明任何特定的順序。關于LIST分區(qū)更詳細的語法信息,請參考13.1.5節(jié),“CREATE TABLE語法” 。 對于下面給出的例子,我們假定將要被分區(qū)的表的基本定義是通過下面的“CREATE TABLE”語句提供的:CREATE TABLE employees ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01', separated D
33、ATE NOT NULL DEFAULT '9999-12-31', job_code INT, store_id INT);(這和18.2.1節(jié),“RANGE分區(qū)” 中的例子中使用的是同一個表)。 假定有20個音像店,分布在4個有經銷權的地區(qū),如下表所示: 地區(qū) 商店ID 號 北區(qū) 3, 5, 6, 9, 17 東區(qū) 1, 2, 10, 11, 19, 20 西區(qū) 4, 12, 13, 14, 18 中心區(qū) 7, 8, 15, 16 要按照屬于同一個地區(qū)商店的行保存在同一個分區(qū)中的方式來分割表,可以使用下面的“CREATE TABLE”語句:CREATE TABLE empl
34、oyees ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01', separated DATE NOT NULL DEFAULT '9999-12-31', job_code INT, store_id INT)PARTITION BY LIST(store_id) PARTITION pNorth VALUES IN (3,5,6,9,17), PARTITION pEast VALUES IN (1,2,10,11,
35、19,20), PARTITION pWest VALUES IN (4,12,13,14,18), PARTITION pCentral VALUES IN (7,8,15,16);這使得在表中增加或刪除指定地區(qū)的雇員記錄變得容易起來。例如,假定西區(qū)的所有音像店都賣給了其他公司。那么與在西區(qū)音像店工作雇員相關的所有記錄(行)可以使用查詢“ALTER TABLE employees DROP PARTITION pWest;”來進行刪除,它與具有同樣作用的DELETE (刪除)查詢“DELETE query DELETE FROM employees WHERE store_id IN (4,
36、12,13,14,18);”比起來,要有效得多。 要點:如果試圖插入列值(或分區(qū)表達式的返回值)不在分區(qū)值列表中的一行時,那么“INSERT”查詢將失敗并報錯。例如,假定LIST分區(qū)的采用上面的方案,下面的查詢將失?。?INSERT INTO employees VALUES (224, 'Linus', 'Torvalds', '2002-05-01', '2004-10-12', 42, 21);這是因為“store_id”列值21不能在用于定義分區(qū)pNorth, pEast, pWest,或pCentral的值列表中找到。要
37、重點注意的是,LIST分區(qū)沒有類似如“VALUES LESS THAN MAXVALUE”這樣的包含其他值在內的定義。將要匹配的任何值都必須在值列表中找到。 LIST分區(qū)除了能和RANGE分區(qū)結合起來生成一個復合的子分區(qū),與HASH和KEY分區(qū)結合起來生成復合的子分區(qū)也是可能的。 關于這方面的討論,請參考18.2.5節(jié),“子分區(qū)”。 18.2.3. HASH分區(qū)18.2.3.1. LINEAR HASH分區(qū)HASH分區(qū)主要用來確保數據在預先確定數目的分區(qū)中平均分布。在RANGE和LIST分區(qū)中,必須明確指定一個給定的列值或列值集合應該保存在哪個分區(qū)中;而在HASH分區(qū)中,MySQL 自動完成這
38、些工作,你所要做的只是基于將要被哈希的列值指定一個列值或表達式,以及指定被分區(qū)的表將要被分割成的分區(qū)數量。 要使用HASH分區(qū)來分割一個表,要在CREATE TABLE 語句上添加一個“PARTITION BY HASH (expr)”子句,其中“expr”是一個返回一個整數的表達式。它可以僅僅是字段類型為MySQL 整型的一列的名字。此外,你很可能需要在后面再添加一個“PARTITIONS num”子句,其中num 是一個非負的整數,它表示表將要被分割成分區(qū)的數量。 例如,下面的語句創(chuàng)建了一個使用基于“store_id”列進行 哈希處理的表,該表被分成了4個分區(qū):CREATE TABLE e
39、mployees ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01', separated DATE NOT NULL DEFAULT '9999-12-31', job_code INT, store_id INT)PARTITION BY HASH(store_id)PARTITIONS 4;如果沒有包括一個PARTITIONS子句,那么分區(qū)的數量將默認為1。 例外: 對于NDB Cluster(簇)表,默認的分區(qū)數
40、量將與簇數據節(jié)點的數量相同,這種修正可能是考慮任何MAX_ROWS 設置,以便確保所有的行都能合適地插入到分區(qū)中。(參見第17章:MySQL簇)。 如果在關鍵字“PARTITIONS”后面沒有加上分區(qū)的數量,將會出現語法錯誤。 “expr”還可以是一個返回一個整數的SQL表達式。例如,也許你想基于雇用雇員的年份來進行分區(qū)。這可以通過下面的語句來實現: CREATE TABLE employees ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01
41、', separated DATE NOT NULL DEFAULT '9999-12-31', job_code INT, store_id INT)PARTITION BY HASH(YEAR(hired)PARTITIONS 4;“expr”還可以是MySQL 中有效的任何函數或其他表達式,只要它們返回一個既非常數、也非隨機數的整數。(換句話說,它既是變化的但又是確定的)。但是應當記住,每當插入或更新(或者可能刪除)一行,這個表達式都要計算一次;這意味著非常復雜的表達式可能會引起性能問題,尤其是在執(zhí)行同時影響大量行的運算(例如批量插入)的時候。 最有效率的哈希函數
42、是只對單個表列進行計算,并且它的值隨列值進行一致地增大或減小,因為這考慮了在分區(qū)范圍上的“修剪”。也就是說,表達式值和它所基于的列的值變化越接近,MySQL就可以越有效地使用該表達式來進行HASH分區(qū)。 例如,“date_col” 是一個DATE(日期)類型的列,那么表達式TO_DAYS(date_col)就可以說是隨列“date_col”值的變化而發(fā)生直接的變化,因為列“date_col”值的每個變化,表達式的值也將發(fā)生與之一致的變化。而表達式YEAR(date_col)的變化就沒有表達式TO_DAYS(date_col)那么直接,因為不是列“date_col”每次可能的改變都能使表達式YE
43、AR(date_col)發(fā)生同等的改變。即便如此,表達式YEAR(date_col)也還是一個用于 哈希函數的、好的候選表達式,因為它隨列date_col的一部分發(fā)生直接變化,并且列date_col的變化不可能引起表達式YEAR(date_col)不成比例的變化。作為對照,假定有一個類型為整型(INT)的、列名為“int_col”的列。現在考慮表達式“POW(5-int_col,3) + 6”。這對于哈希函數就是一個不好的選擇,因為“int_col”值的變化并不能保證表達式產生成比例的變化。列 “int_col”的值發(fā)生一個給定數目的變化,可能會引起表達式的值產生一個很大不同的變化。例如,把列
44、“int_col”的值從5變?yōu)?,表達式的值將產生“1”的改變,但是把列“int_col”的值從6變?yōu)?時,表達式的值將產生“7”的變化。換句話說,如果列值與表達式值之比的曲線圖越接近由等式“y=nx(其中n為非零的常數)描繪出的直線,則該表達式越適合于 哈希。這是因為,表達式的非線性越嚴重,分區(qū)中數據產生非均衡分布的趨勢也將越嚴重。理論上講,對于涉及到多列的表達式,“修剪(pruning)”也是可能的,但是要確定哪些適于 哈希是非常困難和耗時的?;谶@個原因,實際上不推薦使用涉及到多列的哈希表達式。 當使用了“PARTITION BY HASH”時,MySQL將基于用戶函數結果的模數來確定使
45、用哪個編號的分區(qū)。換句話,對于一個表達式“expr”,將要保存記錄的分區(qū)編號為N ,其中“N = MOD(expr, num)”。例如,假定表t1 定義如下,它有4個分區(qū): CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY HASH( YEAR(col3) ) PARTITIONS 4;如果插入一個col3列值為'2005-09-15'的記錄到表t1中,那么保存該條記錄的分區(qū)確定如下: MOD(YEAR('2005-09-01'),4)= MOD(2005,4)= 1MySQL 5.
46、1 還支持一個被稱為“l(fā)inear hashing(線性哈希功能)”的變量,它使用一個更加復雜的算法來確定新行插入到已經分區(qū)了的表中的位置。關于這種算法的描述,請參見18.2.3.1節(jié),“LINEAR HASH分區(qū)” 。 每當插入或更新一條記錄,用戶函數都要計算一次。當刪除記錄時,用戶函數也可能要進行計算,這取決于所處的環(huán)境。 注釋:如果將要分區(qū)的表有一個唯一的鍵,那么用來作為HASH用戶函數的自變數或者主鍵的column_list的自變數的任意列都必須是那個鍵的一部分。18.2.3.1. LINEAR HASH分區(qū)MySQL還支持線性哈希功能,它與常規(guī)哈希的區(qū)別在于,線性哈希功能使用的一個線
47、性的2的冪(powers-of-two)運算法則,而常規(guī) 哈希使用的是求哈希函數值的模數。線性哈希分區(qū)和常規(guī)哈希分區(qū)在語法上的唯一區(qū)別在于,在“PARTITION BY” 子句中添加“LINEAR”關鍵字,如下面所示:CREATE TABLE employees ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01', separated DATE NOT NULL DEFAULT '9999-12-31', job_cod
48、e INT, store_id INT)PARTITION BY LINEAR HASH(YEAR(hired)PARTITIONS 4;假設一個表達式expr, 當使用線性哈希功能時,記錄將要保存到的分區(qū)是num 個分區(qū)中的分區(qū)N,其中N是根據下面的算法得到: 1. 找到下一個大于num.的、2的冪,我們把這個值稱為V ,它可以通過下面的公式得到: 2. V = POWER(2, CEILING(LOG(2, num)(例如,假定num是13。那么LOG(2,13)就是3.7004397181411。 CEILING(3.7004397181411)就是4,則V = POWER(2,4),
49、即等于16)。 3. 設置 N = F(column_list) & (V - 1). 4. 當 N >= num: · 設置 V = CEIL(V / 2) · 設置 N = N & (V - 1) 例如,假設表t1,使用線性哈希分區(qū)且有4個分區(qū),是通過下面的語句創(chuàng)建的:CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR HASH( YEAR(col3) ) PARTITIONS 6;現在假設要插入兩行記錄到表t1中,其中一條記錄col3列值為'200
50、3-04-14',另一條記錄col3列值為'1998-10-19'。第一條記錄將要保存到的分區(qū)確定如下:V = POWER(2, CEILING(LOG(2,7) = 8N = YEAR('2003-04-14') & (8 - 1) = 2003 & 7 = 3 (3 >= 6 為假(FALSE): 記錄將被保存到#3號分區(qū)中)第二條記錄將要保存到的分區(qū)序號計算如下: V = 8N = YEAR('1998-10-19') & (8-1) = 1998 & 7 = 6 (6 >= 4 為真(T
51、RUE): 還需要附加的步驟) N = 6 & CEILING(5 / 2) = 6 & 3 = 2 (2 >= 4 為假(FALSE): 記錄將被保存到#2分區(qū)中)按照線性哈希分區(qū)的優(yōu)點在于增加、刪除、合并和拆分分區(qū)將變得更加快捷,有利于處理含有極其大量(1000吉)數據的表。它的缺點在于,與使用常規(guī)HASH分區(qū)得到的數據分布相比,各個分區(qū)間數據的分布不大可能均衡。18.2.4. KEY分區(qū)按照KEY進行分區(qū)類似于按照HASH分區(qū),除了HASH分區(qū)使用的用戶定義的表達式,而KEY分區(qū)的 哈希函數是由MySQL 服務器提供。MySQL 簇(Cluster)使用函數MD5(
52、)來實現KEY分區(qū);對于使用其他存儲引擎的表,服務器使用其自己內部的 哈希函數,這些函數是基于與PASSWORD()一樣的運算法則。 “CREATE TABLE . PARTITION BY KEY”的語法規(guī)則類似于創(chuàng)建一個通過HASH分區(qū)的表的規(guī)則。它們唯一的區(qū)別在于使用的關鍵字是KEY而不是HASH,并且KEY分區(qū)只采用一個或多個列名的一個列表。 通過線性KEY分割一個表也是可能的。下面是一個簡單的例子: CREATE TABLE tk ( col1 INT NOT NULL, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR KEY (col1)P
53、ARTITIONS 3;在KEY分區(qū)中使用關鍵字LINEAR和在HASH分區(qū)中使用具有同樣的作用,分區(qū)的編號是通過2的冪(powers-of-two)算法得到,而不是通過模數算法。關于該算法及其蘊涵式的描述請參考 18.2.3.1節(jié),“LINEAR HASH分區(qū)” 。 18.2.5. 子分區(qū)子分區(qū)是分區(qū)表中每個分區(qū)的再次分割。例如,考慮下面的CREATE TABLE 語句: CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE(YEAR(purchased) SUBPARTITION BY HASH(TO_DAYS(purcha
54、sed) SUBPARTITIONS 2 ( PARTITION p0 VALUES LESS THAN (1990), PARTITION p1 VALUES LESS THAN (2000), PARTITION p2 VALUES LESS THAN MAXVALUE );表ts 有3個RANGE分區(qū)。這3個分區(qū)中的每一個分區(qū)p0, p1, 和 p2 又被進一步分成了2個子分區(qū)。實際上,整個表被分成了3 * 2 = 6個分區(qū)。但是,由于PARTITION BY RANGE子句的作用,這些分區(qū)的頭2個只保存“purchased”列中值小于1990的那些記錄。 在MySQL 5.1中,對于已
55、經通過RANGE或LIST分區(qū)了的表再進行子分區(qū)是可能的。子分區(qū)既可以使用HASH希分區(qū),也可以使用KEY分區(qū)。這也被稱為復合分區(qū)(composite partitioning)。 為了對個別的子分區(qū)指定選項,使用SUBPARTITION 子句來明確定義子分區(qū)也是可能的。例如,創(chuàng)建在前面例子中給出的同一個表的、一個更加詳細的方式如下: CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE(YEAR(purchased) SUBPARTITION BY HASH(TO_DAYS(purchased) ( PARTITION p0 VALUES LESS THAN (1990
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 項目推廣演講致辭稿
- 個人車輛掛靠租賃公司協(xié)議書
- 2025年柳州a2貨運從業(yè)資格證模擬考試題
- 2025年南京貨運從業(yè)資格證考試模擬考試題庫答案大全
- 小學英語試卷聽力稿
- 書籍設計印刷合同范本文檔
- 個體診所自查報告
- 廈門落戶中介合同范本
- 業(yè)務員個人年度工作總結
- 三年級語文備課組工作總結
- 生理學第六章消化與吸收(供中等衛(wèi)生職業(yè)教育)課件
- 現代文學新詩課件
- 中醫(yī)基礎理論:經絡 第二節(jié) 十二經脈課件
- 家庭急救知識(異物卡喉的急救)共45張課件
- 機臺異常處理規(guī)定
- 旅游地產開發(fā)模式和創(chuàng)新(含案例)
- 診斷學完整教案(共167頁)
- 《汽車文化》全套教案
- 拆除工程檢驗批質量檢驗記錄
- 甲狀腺腫瘤PPT課件
- 城市燃氣工程監(jiān)理實施細則
評論
0/150
提交評論