oracle 分割槽,range-list,範圍-列表複合分割槽
由於工作原因,需要了解一下oracle 分割槽,發現oracle 11g之後分割槽的種類變得更多了。
三種原始分割槽。
(1)範圍分割槽(range);
(2)雜湊分割槽(hash);
(3)列表分割槽(list);
Range分割槽例子:
create table pdba (id number, time date) partition by range (time) ( partition p1 values less than (to_date('2010-10-1', 'yyyy-mm-dd')), partition p2 values less than (to_date('2010-11-1', 'yyyy-mm-dd')), partition p3 values less than (to_date('2010-12-1', 'yyyy-mm-dd')), partition p4 values less than (maxvalue) )
Hash分割槽例子:
create table test
(
transaction_id number primary key,
item_id number(8) not null
)
partition by hash(transaction_id)
(
partition part_01 tablespace tablespace01,
partition part_02 tablespace tablespace02,
partition part_03 tablespace tablespace03
);
List分割槽例子:
create table custaddr ( id varchar2(15 byte) not null, areacode varchar2(4 byte) ) partition by list (areacode) ( partition t_list025 values ('025'), partition t_list372 values ('372') , partition t_list510 values ('510'), partition p_other values (default) )
oralce 11g在原始分割槽的基礎上,可以實現父子分割槽,在三種原始分割槽的基礎上,可以實現 3*3=9種,父子分割槽。
自主學習,建立分割槽和子分割槽
由於公司需要為表增加分割槽,我採用的形式range-list,因為此表是按照工作日進行增加資料。
做了一個例子:
create table bep_part_test (zzzid varchar2(100) primary key, work_date date, csbh varchar2(2) ) partition by range (work_date)subpartition by list (csbh) (partition bep_2006_07 values less than (to_date('2006-7-1','yyyy-mm-dd')) ( subpartition bep_2006_07_10 values ('10'), subpartition bep_2006_07_20 values ('20'), subpartition bep_2006_07_30 values ('30'), subpartition bep_2006_07_40 values ('40'), subpartition bep_2006_07_50 values ('50'), subpartition bep_2006_07_default values (default) ), partition bep_2007_01 values less than (to_date('2007-1-1','yyyy-mm-dd')) ( subpartition bep_2007_01_10 values ('10'), subpartition bep_2007_01_20 values ('20'), subpartition bep_2007_01_30 values ('30'), subpartition bep_2007_01_40 values ('40'), subpartition bep_2007_01_50 values ('50'), subpartition bep_2007_01_default values (default) ), partition bep_maxvalue values less than (maxvalue) ); commit;
開始折騰子分割槽
我現在想在父分割槽bep_2007_01中增加一個字分割槽subpartition bep_2007_01_60 values ('60');
alter table bep_part_test
modify partition bep_2007_01
add subpartition bep_2007_01_60 values ('60');
commit;
oracle 11g 這時報錯了:ORA-14621:在DEFAULT子分割槽已存在時無法新增子分割槽
這時,第一個想法就是將預設子分割槽刪除,並且重新構60的子分割槽,並且重新建立預設子分割槽。
哪如果預設子分割槽中存在資料。那資料將會去哪裡?
先增加一條資料:
insert into bep_part_test values('111',to_date('21-9-2006','dd-mm-yyyy'),'60');
commit;
先查詢父分割槽,
select * from bep_part_test partition(bep_2007_01)
查詢出來資料
1 111 06/9/21 60
再查詢子分割槽
select * from bep_part_test subpartition(bep_2007_01_default)
查詢出來資料1 111 06/9/21 60
刪除子分割槽
alter table bep_part_test drop subpartition bep_2007_01_default;
commit;
這時查詢父分割槽
select * from bep_part_test partition(bep_2007_01);
資料不見了。。。
然後查詢表的所有資料
select * from bep_part_test
資料不見了。。。這說明刪除分割槽的同時會將分割槽內的資料同時刪除。
這時,我再將刪除的預設子分割槽加回去。
alter table bep_part_test modify partition bep_2007_01 add subpartition bep_2007_01_default values (default);
commit;
成功。
然後將剛剛那條記錄插入回去。
insert into bep_part_test values('111',to_date('21-9-2006','dd-mm-yyyy'),'60');
commit;
這時,資料庫報錯了。
ORA-01502:索引'TIGER.SYS_C00248918'或這類索引的分割槽處於不可用狀態。
還以為連資料都刪除了呢。結果竟然插入不進去。
再查詢無效索引
select <code class="sql plain">index_name ,status </code> from user_indexes where Status = 'UNUSABLE';
再將無效索引重鑄
alter index SYS_C00248918 rebuild ;
commit;
然後再插入了。成功了。
這時,我又將bep_2007_01_default 預設分割槽刪除了。並且重鑄了無效的索引。
再插入剛剛那個資料:
報錯了:ORA-14400:插入的分割槽關鍵字未對映到任何分割槽。
說明沒有預設分割槽,當超出子分割槽之後,還是會報錯的。
我最開始的想法,是不應該以前的資料,並增加一個子分割槽,發現這樣是不行的。
經過詢問各種大神,找到辦法了。現將原表還原。
然後插入資料。
再進行拆子分割槽。
alter table bep_part_test split
subpartition bep_2007_01_default values ('60') into
(subpartition bep_2007_01_60, subpartition bep_2007_01_default);
commit;
成功了。那麼查詢一下資料:
select * from bep_part_test subpartition(bep_2007_01_60)
資料出現了:1 111 06/9/21 60
這樣就在沒有影響原有資料的情況下,拆分了子分割槽。
既然分割槽可以拆,那麼分割槽應該也可以合併啊。
alter table bep_part_test merge subpartitions
bep_2007_01_60,bep_2007_01_default into subpartition bep_2007_01_default;
commit;
合併成功查詢資料:
select * from bep_part_test subpartition(bep_2007_01_default)
資料存在
再增加資料的時候
insert into bep_part_test values('11111',to_date('21-9-2006','dd-mm-yyyy'),'70');
commit;
報錯了,之前的那個索引遊離狀態。需要重鑄。
再次重新做合併的試驗,發現合併後再插入同樣出現索引遊離狀態,同樣需要重鑄一下。
為了不那麼繁瑣,可以直接在後面加上 update indexs
這樣操作:
alter table bep_part_test merge subpartitions
bep_2007_01_60,bep_2007_01_default into subpartition bep_2007_01_default UPDATE INDEXES;
commit;
哇塞,是不是可以直接插入了。。不用重鑄了。。。
這個子分割槽是折騰明白了。
開始折騰父分割槽吧
現在將預設的父分割槽進行拆開。
先插入兩條資料:
insert into bep_part_test values('22',to_date('21-9-2007','dd-mm-yyyy'),'60');
commit;
insert into bep_part_test values('21',to_date('21-4-2007','dd-mm-yyyy'),'60');
commit;
查詢一下資料:
select * from bep_part_test partition(bep_maxvalue);
資料兩條
1 22 07/9/21 60
2 21 07/4/21 60
現在將父分割槽的最大預設分割槽,拆分成2007-07 和最大預設分割槽:
alter table bep_part_test split
partition bep_maxvalue at (to_date('2007-7-1','yyyy-mm-dd')) into
(partition bep_2007_07, partition bep_maxvalue) UPDATE INDEXES;
commit;
拆分成功!
查詢資料:
select * from bep_part_test partition(bep_maxvalue);
1 22 07/9/21 60
select * from bep_part_test partition(bep_2007_07);
1 21 07/4/21 60
資料顯示正確!
最大值拆分沒有問題。
現在要是拆分已有子分割槽的父分割槽,會成功嗎?
先插入兩條2006-08的資料
insert into bep_part_test values('281',to_date('22-8-2006','dd-mm-yyyy'),'60');
commit;
insert into bep_part_test values('282',to_date('21-8-2006','dd-mm-yyyy'),'60');
commit;
查詢資料:
select * from bep_part_test partition(bep_2007_01);
1 1111 06/9/21 10
2 111 06/9/21 60
3 111211 06/9/21 60
4 11111 06/9/21 70
5 111111 06/9/21 70
6 281 06/8/22 60
7 282 06/8/21 60
有一些是之前做實驗的資料。主要我是想從9月份進行拆這個父分割槽
拆分語句如下:
alter table bep_part_test split
partition bep_2007_01 at (to_date('2006-9-1','yyyy-mm-dd')) into
(partition bep_2006_09, partition bep_2007_01) UPDATE INDEXES;
commit;
查詢資料:
select * from bep_part_test partition(bep_2007_01);
資料如下:
1 1111 06/9/21 10
2 111 06/9/21 60
3 111211 06/9/21 60
4 11111 06/9/21 70
5 111111 06/9/21 70
查詢資料:
select * from bep_part_test partition(bep_2006_09);
資料如下:
1 281 06/8/22 60
2 282 06/8/21 60
說明拆分成功。
實驗告一段落了。。。