- 為了提高數據在大數據量讀寫操作和查詢時的效率,DM提供了對表和索引進行分區的技術。把表和索引等數據庫對象中的數據分割成小的單位,分別存放在一個個單獨的段中,用戶對表的訪問轉化為對較小段的訪問,以改善大型應用系統的性能。
- DM提供了水平分區方式和垂直分區方式(開發版好像不支持垂直分區表,語法:CREATE TABLE TEST (A INT,B VARCHAR) PARTITION BY COLUMN(“A” AS P1,”B” AS P2);)。水平分區包括范圍、哈希和列表三種方式。
- 分區是指將表、索引等數據庫對象划分為較小的可管理片段的技術,每一個片段稱為分區子表或分區索引。一個表被分區后,對表的查詢操作可以局限於某個分區進行分區,而不是整個表,這個可以大大提高查詢速度。
- DM采用子表方式創建分區表,分區表作為分區主表,而每一個分區以一個子表實體存在,即每一個分區都是一個完整的表,一般命名為主表名_分區名。對於水平分區,子表跟主表具有相同的邏輯結構,即分區子表與分區主表有相同的列定義和約束定義。在DM分區表中,分區主表本身不存儲數據,所有數據只存儲在子表中,從而實現不同分區的完全獨立性。水平分區子表刪除后,會將子表上的數據一起刪除。
- 由於每一個分區都以一個子表作為實體,那么不同分區可以存儲在相同表空間,也可以位於不同的表空間中。也可以設置自己單獨的存儲屬性。
- DM還支持多級分區表,可以將列表、哈希、范圍三種分區方式進行任意組合,將表進行多次分區。
- 水平分區表的ROWID與其主表屬性一致:LIST表(堆表)的水平分區表的ROWID是物理的;普通表的水平分區表的ROWID是邏輯的,且每個子表的ROWID都是從1開始增長,但是最終返回前,ROWID的高字節會補充上子表序號。
- 范圍分區是按照某個列或某幾個列的值的范圍來創建分區,當用戶向表中寫入數據時,數據庫服務器將按照這些列上的值進行判斷,將數據寫入相應的分區中。在創建范圍分區時,首先要指定分區列,即按照哪些列進行分區,然后為每個分區指定數據范圍。范圍分區支持MAXVALUE范圍值的使用,MAXVALUE相當於一個比任何都大的值。值得注意的是,MAXVALUE之間無法比較大小。示例:CREATE TABLE TEST(A INT,B VARCHAR) PARTITION BY RANGE(A)(PARTITION P1 VALUES LESS THAN (10),PARTITION P2 VALUES EQU OR LESS THAN (MAXVALUE));
- 創建范圍分區,需要注意的是,LIST分區的分區鍵必須唯一。示例:CREATE TABLE TEST (A INT,B VARCHAR) PARTITION BY LIST(B)(PARTITION P1 VALUES (‘HAHA’),PARTITION P2 VALUES (DEFAULT)); //這里的DEFAULT指的是除以上取值外的其它任意值。
- 在很多情況下,用戶無法預測某個列上的數據變化范圍,因而無法實現創建固定數量的范圍分區或LIST分區。在這種情況下,DM哈希分區提供了一種在指定數量的分區中均等的划分數據的方法,基於分區鍵的散列值將行映射到分區中。當用戶向表中寫入數據時,數據服務器將根據一個哈希函數對數據進行計算,把數據均勻的分布在各個分區中。在哈希分區中,用戶無法預測數據將被寫入哪個分區。示例:CREATE TABLE TEST (A INT,B VARCHAR) PARTITION BY HASH(B)(PARTITION P1,PARTITION P2);或者:CREATE TABLE TEST (A INT,B VARCHAR) PARTITION BY HASH(B) PARTITIONS 2;
- 在很多情況下,經過一次分區並不能精確地對數據進行分類,這時需要多級分區。示例:CREATE TABLE TEST(A INT,B VARCHAR) PARTITION BY RANGE(A)SUBPARTITION BY LIST(B) SUBPARTITION TEMPLATE( SUBPARTITION P1 VALUES (‘HAHA’), SUBPARTITION P2 VALUES (DEFAULT))(PARTITION P11 VALUES LESS THAN (10) (SUBPARTITION P11_1 VALUES (‘HAHA’), SUBPARTITION P11_2 VALUES (‘HEHE’), SUBPARTITION P11_3 VALUES (DEFAULT)),PARTITION P22 VALUES EQU OR LESS THAN(MAXVALUE));
- DM支持最多八層多級分區。
- 當執行SELECT命令時,可以指定查詢某個分區上的數據,如:SELECT * FROM TEST PARTITION(P1);
- DM支持對水平分區表建立普通索引、唯一索引、聚集索引和函數索引。創建索引時若未指定GLOBAL關鍵字則建立的索引是局部索引,即每一個表分區都有一個索引分區,並且只索引該分區上的數據。若指定了GLOBAL關鍵字,則建立的索引是全局索引,即每個表分區的數據都被索引在同一個B樹中。目前,只有堆表的水平分區表支持GLOBAL全局索引。堆表上的primary key會自動變為全局索引。如:CREATE INDEX IDX ON TEST(A) GLOBAL; (TEST為堆分區表)
- 對於非全局索引而言,建立分區索引后,每一個分區子表都會建立一個分區索引,負責索引分區子表的數據。由於每個索引分區只負責索引本分區上的數據,其它分區上的數據無法維護,因此當對水平分區表建立非全局唯一索引時,只能建立分區鍵索引,即分區鍵必須全都包含在索引鍵中。只有當分區鍵都包含在索引鍵中,才能對分區主表保證索引鍵唯一。全局唯一索引不受此約束。另外,不能在水平分區表上建立局部唯一函數索引。
- DM提供了對水平分區表的修改,功能包括:增加分區(只能對范圍分區和LIST分區增加分區)、刪除分區(只能對范圍分區和LIST分區進行刪除分區)、合並分區(只能在范圍分區上進行合並分區)、拆分分區(只能在范圍分區上進行拆分分區)、交換分區(普通表必須和分區表同構,擁有相同的列和索引,不支持含有加密列的分區表交換分區)。
- 增加分區:DM支持用ALTER TABLE ADD PARTITION語句將新增分區增加到最后一個現存分區的后面。對於范圍分區,增加分區必須在最后一個分區范圍值的后面增加,要想在表的開始范圍或中間范圍增加,應使用SPLIT PARTITION語句。當已經存在MAXVALUE分區時,不允許增加分區。如:ALTER TABLE TEST ADD PARTITION P3 VALUES LESS THAN (30);;對於LIST分區,增加分區包含的離散值不能已存在與某個分區中,當已經存在DEFAULT分區時,不允許增加分區。如:ALTER TABLE TEST ADD PARTITION P3 VALUES (‘HEHE’); 只能對范圍分區和LIST分區增加分區,不能對哈希分區增加分區,並且增加分區不會影響分區索引,因為分區索引只是局部索引,新增分區僅僅是新增分區子表,並更新分區主表的分區信息,其它分區並不發生改變。
- 刪除分區:DM支持用ALTER TABLE DROP PARTITION語句將分區刪除。如:ALTER TABLE TEST DROP PARTITION P3; 只能對范圍分區和LIST分區進行刪除分區,哈希分區不支持刪除分區。跟增加分區一樣,刪除分區不會影響分區索引。
- 交換分區:ALTER TABLE EXCHANGE PARTITION WITH TABLE;僅范圍分區和LIST分區支持交換分區,哈希分區不支持。並且分區交換要求分區表跟交換表具有相同的結構(相同的表類型、相同的BRANCH選項、相同的列結構、相同的索引、相同的分布方式),分區交換並不會校驗數據,如交換表的數據是否符合分區范圍等,即不能保證分區交換后的分區上的數據符合分區范圍。交換分區采用數據字典信息交換的技術,幾乎不涉及IO操作,因此效率非常高。進行交換的兩張表,若包含加密列,對應的加密列要求加密信息完全一致(前面不是說不支持含有加密列的分區表進行分區交換嗎?試了,報錯交換對象不匹配)如:ALTER TABLE TEST EXCHANGE PARTITION P1 WITH TABLE TEST_A;
- 合並分區:要想將兩個范圍分區的內容合並到一個分區,就要使用ALTER TABLE MERGE PARTITIONS語句。若分區的數據很少,或相對其他分區某些分區的數據量較少,導致IO不均衡,可以考慮使用合並分區。如:ALTER TABLE TAB_NAME MERGE PARTITIONS P1,P2 INTO PARTITION P3; 僅范圍分區支持合並分區,並且合並的分區必須是范圍相鄰的兩分區。另外,合並的分區會導致數據的重組和分區索引的重建,因此合並分區可能會比較耗時,所需時間取決於分區數據量的大小。
- 拆分分區:ALTER TABLE TAB_NAME SPLIT PARTITION P3 AT () INTO (PARTITION P3_1,PARTITION P3_2); 用於將一分區中的內容重新划分成兩個新的分區,當一個分區變得太大以至於要用很長時間才能完成備份、恢復或維護操作時,就應考慮做分割分區的工作,還可以用SPLIT PARTITION子句來重新划分IO負載。僅范圍分區表支持拆分分區,拆分分區會導致數據的重組和分區索引的重建,因此拆分分區可能會比較耗時,所需時間取決於分區數據量的大小。
- 間隔分區表:僅支持一級范圍分區創建間隔分區,且只能有一個分區列,分區列類型為日期或數值。示例:CREATE TABLE TEST(A INT,B VARCHAR) PARTITION BY (A) INTERVAL (10)(PARTITION P1 VALUES LESS THAN(10)); //使用INTERVAL之后,就不用手工增加分區,來適應數據的增長。
- DM水平分區表有如下限制:分區列類型必須是數值型、字符型或日期型;范圍分區和哈希分區的分區鍵可以多個,最多不超過16個,LIST分區的分區鍵必須唯一;水平分區表指定主鍵和唯一約束時,分區鍵都必須包含在主鍵和唯一約束中;水平分區表不支持臨時表;不能在水平分區表上建立自引用約束;普通環境中,水平分區表的各級分區的總和上限是65535,MPP環境下,水平分區表的各級分區總數上限取決於INI參數MAX_EP_SITES,上限為2^(16-log2MAX_EP_SITES);不允許對分區子表執行任何DDL操作;哈希分區支持重命名(ALTER TABLE TEST RENAME PARTITION P1 TO P3;)、刪除約束、設置觸發器是否啟用的操作;范圍分區支持分區合並、拆分、增加、刪除、交換、重命名、刪除約束、設置觸發器是否生效操作;LIST分區支持分區增加、刪除、交換、重命名、刪除約束、設置觸發器是否生效操作;LIST分區范圍值不能為NULL;LIST分區子表范圍值個數與數據頁大小和相關系統表列長度相關,4K頁,單個子表最多支持120個范圍值,8K頁,單個子表最多支持254個范圍值,16/32K頁,單個子表最多支持270個范圍值;對范圍分區增加分區值必須是遞增的,即只能在最后一個分區后添加分區,LIST分區增加分區值不能存在於其它已存在分區;當分區數僅剩一個時,不允許刪除分區;僅能對相鄰的范圍分區進行合並,合並后的分區名可以為高分區名或新分區名;拆分分區的分區值必須在原分區范圍中,並且分區名不能跟已有分區名相同;與分區進行分區交換的普通表,必須與分區表擁有相同的列及索引,但交換分區並不會對數據進行校驗,即交換后的數據並不能保證數據完整性,如CHECK約束,分區表與普通表創建的索引順序要求一致;水平分區表僅支持建立局部索引,不支持建立全局索引,即在分區表上建立索引,每一個表分區都有一個索引分區,並且只索引該分區上的數據,而分區主表上的索引並不索引數據;不能對水平分區表建立唯一函數索引和全文索引;不能對分區子表單獨建立索引;在未指定ENABLE ROW MOVEMENT的分區表上(CREATE TABLE TEST (A INT,B VARCHAR) PARTITION BY RANGE(A) (PARTITION P1 VALUES LESS THAN(10),PATITION P2 VALUES EQU OR LESS THAN (MAXVALUE)) ENABLE ROW MOVEMENT;)執行更新分區鍵,不允許更新后數據發生跨分區的移動,即不能有行遷移(這里的更新分區鍵指的是UPDATE);不能在分區語句的STORAGE子句中指定BRANCH選項;不允許引用水平分區子表作為外鍵約束;多級分區最多支持八層;多級分區表支持以下修改操作:新增分區、新增列、刪除列、刪除表級約束、修改表名、設置與刪除列的默認值、設置列NULL屬性、設置列可見性、設置行遷移屬性、啟用超長記錄、with delta(沒用過,不知道啥意思,sql手冊里有介紹,該選擇專門針對huge表)、新增子分區、刪除子分區、修改二級分區模板信息;水平分區表支持的列修改操作除了多級分區表支持的操作外,還支持:設置觸發器生效/失效、修改列名、修改列屬性、增加表級約束、刪除分區、SPLIT/MERGE分區和交換分區;水平分區表中包含大字段、自定義字段列、則定義時指定ENABLE ROW MOVEMENT參數無效,即不允許更新后數據發生跨分區的移動;
- 間隔分區表的限制說明:僅支持一級范圍分區創建間隔分區;只能有一個分區列,且分區列類型為日期或數值;對間隔分區進行SPLIT,只能在間隔分區范圍內進行操作;被SPLIT/MERGE的分區,其左側分區不再自動進行創建;不相鄰的間隔的分區,不能MERGE;表定義不能包含MAXVALUE分區;不允許新增分區;不能刪除起始間隔分區;間隔分區表定義語句顯示到起始間隔分區為止;自動生成的間隔分區,均不包含邊界值;間隔表達式只能為常量或日期間隔函數,日期間隔函數為NUMTOYMINTERVAL、NUMTODSINTERVAL,數值常量可以為整性、DEC