1. 程式人生 > >Oracle建立表分割槽

Oracle建立表分割槽

直接進入主題----可以這樣理解,當一個數據表在插入資料的時候,在幾百條或者幾千條資料中查詢目標資料的時候不會花費多長時間,最多一兩秒!但是隨著資料的不斷增加,當達到上萬條或者幾百萬條的時候,當你在查詢某個資料,這是可能會花費幾分鐘,甚至會導致系統掛掉!這個時候就需要考慮分割槽!
分割槽條件:

  • 表的大小超過2GB;
  • 表中含有歷史資料,新的資料被增加到新的分割槽中.
優點:
  • 提高查詢的效能:對分割槽物件的查詢可以
  • 提高可用性:如果某個分割槽出現故障,表在其他分割槽的資料依然可以使用
  • 維護方便:如果某個表出現故障,需要修復資料,質修復該分割槽即可
  • 均衡I/O:可以吧不同的分割槽對映到磁碟以平衡I/O,改善整個系統性能。

缺點:
    分割槽表相關:已經存在的表沒有方法可以直接轉化為分割槽,不過Oracle提供了線上重定義表的功能
分割槽的幾種型別及操作方法:範圍分割槽、雜湊分割槽、列表分割槽、複合分割槽

範圍分割槽:

顧名思義,就是根據某個值,根據給定值的範圍將整個表分割槽,就像分數等級一樣;

create table partition_range (
    id number(19,0) not null,
    name varchar2(128 char) not null,
    score number(10,0) not null,
    primary key(id)
)partition by range(score)
(
  partition bujige values less than(60), --不及格  
  partition jige values less than(85), --及格  
  partition youxiu values less than(maxvalue) --優秀  
<p>);<span style="font-family:Microsoft YaHei;font-size:14px;">
</span></p><p>
</p>

根據欄位‘score’的範圍分成不及格、及格和優秀三個分割槽,給定值的範圍
插入測試資料

insert into partition_range values(1,'sd1',54);
insert into partition_range values(2,'sd2',65);
insert into partition_range values(3,'sd3',87);
insert into partition_range values(4,'sd4',90);
insert into partition_range values(5,'sd5',76);

資料不多,但是每個分割槽都有

查詢語句:

select * from partition_range 
select * from partition_range partition(bujige)
select * from partition_range partition(jige)
select * from partition_range partition(youxiu)
結果分別是:

全部

不及格

及格


優秀


需要注意的三點:

1、每一個分割槽都必須有一個VALUES LESS THEN子句,它指定了一個不包括在該分割槽中的上限值。分割槽鍵的任何值等於或者大於這個上限值的記錄都會被加入到下一個高一些的分割槽中。 2、所有分割槽,除了第一個,都會有一個隱式的下限值,這個值就是此分割槽的前一個分割槽的上限值。 3、在最高的分割槽中,MAXVALUE被定義。MAXVALUE代表了一個不確定的值。這個值高於其它分割槽中的任何分割槽鍵的值,也可以理解為高於任何分割槽中指定的VALUE LESS THEN的值,同時包括空值 列表分割槽: 根據資料表中的某個欄位分割槽。還是上一個表的創表語句,分割槽語句改變了:
create table partition_list (
    id number(19,0) not null,
    name varchar2(128 char) not null,
    score number(10,0) not null,
    primary key(id)
)partition by list(name)
(
  partition sd1 values('sd1'), 
  partition sd2 values('sd2'), 
  partition sd3 values('sd3') 
);
根據欄位'name'具體的值分割槽,不是給定範圍而是給定值
插入語句:
insert into partition_list values(1,'sd1',60);
insert into partition_list values(2,'sd2',65);
insert into partition_list values(3,'sd2',60);
insert into partition_list values(4,'sd3',85);
insert into partition_list values(5,'sd3',87);
insert into partition_list values(6,'sd3',85);
insert into partition_list values(7,'sd3',100);
查詢語句:
select * from partition_list 
select * from partition_list partition(sd1)
select * from partition_list partition(sd2)
select * from partition_list partition(sd3)
結果: 全部 分割槽sd1:

分割槽sd2:


分割槽sd3:


以上兩個很好區別,根據欄位值的範圍和具體值來分割槽。

雜湊分割槽:
雜湊分割槽是根據欄位的hash值進行均勻分佈,儘可能的實現各分割槽所雜湊的資料相等。
創表語句:

create table partition_hash (
    id number(19,0) not null,
    name varchar2(128 char) not null,
    score number(10,0) not null,
    primary key(id)
)partition by hash(id)
(
  partition sd1, 
  partition sd2, 
  partition sd3 
);

和以上有區別,直接給定分割槽名就可以了
查詢結果
分割槽sd1

分割槽sd2

分割槽sd3


注意:雜湊分割槽即為雜湊分割槽,Oracle採用雜湊碼技術分割槽,分割槽方式有Oracle的雜湊演算法為主,也可能下一次搜尋就不是這個資料了

複合分割槽:

複合分割槽就是將上面的三個方法組合比如範圍-列表,範圍-雜湊...,Oracle 11g裡還有個間隔分割槽於是複合也就多了間隔-列表,間隔雜湊等分割槽,這幾天被範圍和列表分割槽搞死了,就介紹範圍---列表分割槽吧,對了列表分割槽不支援多列,但是範圍分割槽和雜湊分割槽支援多列

先看看一張圖:


將資料分成ABC三個分割槽,然後再分別分成子分割槽如A又分成xyz三個小分割槽,注意呼叫分割槽使用的名字,下面會講解

首先是普通的建立

create table MobileMessage  
(  
 ACCT_MONTH VARCHAR2(6), -- 帳期 格式:年月 YYYYMM  
 AREA_NO VARCHAR2(10), -- 地域號碼   
 DAY_ID VARCHAR2(2), -- 本月中的第幾天 格式 DD  
 SUBSCRBID VARCHAR2(20), -- 使用者標識   
 SVCNUM VARCHAR2(30) -- 手機號碼  
)  
partition by range(ACCT_MONTH,AREA_NO) subpartition by list(DAY_ID)  
(  
  partition p1 values less than('200705','012')  
  (  
    subpartition shangxun1 values('01','02','03','04','05','06','07','08','09','10'),  
    subpartition zhongxun1 values('11','12','13','14','15','16','17','18','19','20'),  
    subpartition xiaxun1 values('21','22','23','24','25','26','27','28','29','30','31')  
  ),  
  partition p2 values less than('200709','014')  
  (  
    subpartition shangxun2 values('01','02','03','04','05','06','07','08','09','10'),  
    subpartition zhongxun2 values('11','12','13','14','15','16','17','18','19','20'),  
    subpartition xiaxun2 values('21','22','23','24','25','26','27','28','29','30','31')  
  ),  
  partition p3 values less than('200801','016')  
  (  
    subpartition shangxun3 values('01','02','03','04','05','06','07','08','09','10'),  
    subpartition zhongxun3 values('11','12','13','14','15','16','17','18','19','20'),  
    subpartition xiaxun3 values('21','22','23','24','25','26','27','28','29','30','31')  
  )  
)  
注意上面的格式,partition後面跟著subpartition,這個就是對每個分割槽下建立三個小分割槽,然後插入資料
insert into MobileMessage values('200701','010','04','ghk001','13800000000');  
insert into MobileMessage values('200702','015','12','myx001','13633330000');  
insert into MobileMessage values('200703','015','24','hjd001','13300000000');  
insert into MobileMessage values('200704','010','04','ghk001','13800000000');  
insert into MobileMessage values('200705','010','04','ghk001','13800000000');  
insert into MobileMessage values('200705','011','18','sxl001','13222000000');  
insert into MobileMessage values('200706','011','21','sxl001','13222000000');  
insert into MobileMessage values('200706','012','11','tgg001','13800044400');  
insert into MobileMessage values('200707','010','04','ghk001','13800000000');  
insert into MobileMessage values('200708','012','24','tgg001','13800044400');  
insert into MobileMessage values('200709','014','29','zjj001','13100000000');  
insert into MobileMessage values('200710','014','29','zjj001','13100000000');  
insert into MobileMessage values('200711','014','29','zjj001','13100000000');  
insert into MobileMessage values('200711','013','30','wgc001','13444000000');  
insert into MobileMessage values('200712','013','30','wgc001','13444000000');  
insert into MobileMessage values('200712','010','30','ghk001','13800000000');  
insert into MobileMessage values('200801','015','22','myx001','13633330000');  
查詢:

全部資料


這樣建立分割槽後,查詢子分割槽就直接寫子分割槽的名字,這樣的方法對分割槽少的的很合適,但是要是遇到分割槽幾千個,這就不適用了,所以就有了帶模板的分割槽

create table MobileMessage  
(  
 ACCT_MONTH VARCHAR2(6), -- 帳期 格式:年月 YYYYMM  
 AREA_NO VARCHAR2(10), -- 地域號碼  
 DAY_ID VARCHAR2(2), -- 本月中的第幾天 格式 DD  
 SUBSCRBID VARCHAR2(20), -- 使用者標識   
 SVCNUM VARCHAR2(30) -- 手機號碼  
)  
partition by range(ACCT_MONTH,AREA_NO) subpartition by list(DAY_ID)  
subpartition template  
(  
 subpartition sub1 values('01'),subpartition sub2 values('02'),  
 subpartition sub3 values('03'),subpartition sub4 values('04'),  
 subpartition sub5 values('05'),subpartition sub6 values('06'),  
 subpartition sub7 values('07'),subpartition sub8 values('08'),  
 subpartition sub9 values('09'),subpartition sub10 values('10'),  
 subpartition sub11 values('11'),subpartition sub12 values('12'),  
 subpartition sub13 values('13'),subpartition sub14 values('14'),  
 subpartition sub15 values('15'),subpartition sub16 values('16'),  
 subpartition sub17 values('17'),subpartition sub18 values('18'),  
 subpartition sub19 values('19'),subpartition sub20 values('20'),  
 subpartition sub21 values('21'),subpartition sub22 values('22'),  
 subpartition sub23 values('23'),subpartition sub24 values('24'),  
 subpartition sub25 values('25'),subpartition sub26 values('26'),  
 subpartition sub27 values('27'),subpartition sub28 values('28'),  
 subpartition sub29 values('29'),subpartition sub30 values('30'),  
 subpartition sub31 values('31')  
)  
(  
  partition p_0701_010 values less than('200701','011'),  
  partition p_0701_011 values less than('200701','012'),  
  partition p_0701_012 values less than('200701','013'),  
  partition p_0701_013 values less than('200701','014'),  
  partition p_0701_014 values less than('200701','015'),  
  partition p_0701_015 values less than('200701','016'),  
  partition p_0702_010 values less than('200702','011'),  
  partition p_0702_011 values less than('200702','012'),  
  partition p_0702_012 values less than('200702','013'),  
  partition p_0702_013 values less than('200702','014'),  
  partition p_0702_014 values less than('200702','015'),  
  partition p_0702_015 values less than('200702','016'),  
  partition p_0703_010 values less than('200703','011'),  
  partition p_0703_011 values less than('200703','012'),  
  partition p_0703_012 values less than('200703','013'),  
  partition p_0703_013 values less than('200703','014'),  
  partition p_0703_014 values less than('200703','015'),  
  partition p_0703_015 values less than('200703','016'),    
  partition p_0704_010 values less than('200704','011'),  
  partition p_0704_011 values less than('200704','012'),  
  partition p_0704_012 values less than('200704','013'),  
  partition p_0704_013 values less than('200704','014'),  
  partition p_0704_014 values less than('200704','015'),  
  partition p_0704_015 values less than('200704','016'),    
  partition p_0705_010 values less than('200705','011'),  
  partition p_0705_011 values less than('200705','012'),  
  partition p_0705_012 values less than('200705','013'),  
  partition p_0705_013 values less than('200705','014'),  
  partition p_0705_014 values less than('200705','015'),  
  partition p_0705_015 values less than('200705','016'),    
  partition p_0706_010 values less than('200706','011'),  
  partition p_0706_011 values less than('200706','012'),  
  partition p_0706_012 values less than('200706','013'),  
  partition p_0706_013 values less than('200706','014'),  
  partition p_0706_014 values less than('200706','015'),  
  partition p_0706_015 values less than('200706','016'),    
  partition p_0707_010 values less than('200707','011'),  
  partition p_0707_011 values less than('200707','012'),  
  partition p_0707_012 values less than('200707','013'),  
  partition p_0707_013 values less than('200707','014'),  
  partition p_0707_014 values less than('200707','015'),  
  partition p_0707_015 values less than('200707','016'),    
  partition p_0708_010 values less than('200708','011'),  
  partition p_0708_011 values less than('200708','012'),  
  partition p_0708_012 values less than('200708','013'),  
  partition p_0708_013 values less than('200708','014'),  
  partition p_0708_014 values less than('200708','015'),  
  partition p_0708_015 values less than('200708','016'),    
  partition p_0709_010 values less than('200709','011'),  
  partition p_0709_011 values less than('200709','012'),  
  partition p_0709_012 values less than('200709','013'),  
  partition p_0709_013 values less than('200709','014'),  
  partition p_0709_014 values less than('200709','015'),  
  partition p_0709_015 values less than('200709','016'),    
  partition p_0710_010 values less than('200710','011'),  
  partition p_0710_011 values less than('200710','012'),  
  partition p_0710_012 values less than('200710','013'),  
  partition p_0710_013 values less than('200710','014'),  
  partition p_0710_014 values less than('200710','015'),  
  partition p_0710_015 values less than('200710','016'),    
  partition p_0711_010 values less than('200711','011'),  
  partition p_0711_011 values less than('200711','012'),  
  partition p_0711_012 values less than('200711','013'),  
  partition p_0711_013 values less than('200711','014'),  
  partition p_0711_014 values less than('200711','015'),  
  partition p_0711_015 values less than('200711','016'),    
  partition p_0712_010 values less than('200712','011'),  
  partition p_0712_011 values less than('200712','012'),  
  partition p_0712_012 values less than('200712','013'),  
  partition p_0712_013 values less than('200712','014'),  
  partition p_0712_014 values less than('200712','015'),  
  partition p_0712_015 values less than('200712','016'),    
  partition p_0801_010 values less than('200801','011'),  
  partition p_0801_011 values less than('200801','012'),  
  partition p_0801_012 values less than('200801','013'),  
  partition p_0801_013 values less than('200801','014'),  
  partition p_0801_014 values less than('200801','015'),  
  partition p_0801_015 values less than('200801','016'),    
  partition p_other values less than(maxvalue, maxvalue)  
);  
注意這個建立格式,先將子分割槽的模板建立好,在寫父分割槽,好處就是,沒建立一個父分割槽的時候,子分割槽就會根據模板自動建立,不需要認為的新增,插入的資料和上面的一樣,下面顯示查詢結果,注意查詢子分割槽時候使用的名字

注意!!!



需要因為是自動生成的,所以格式就起了作用,父分割槽+“_”+子分割槽

還有一個就是less then的問題,範圍分割槽 range(A,B)的分割槽法則,範圍分割槽都是 values less than(A,B)的,通常情況下以A為準,如果小於A的不用考慮B,直接插進去,如果等於A那麼考慮B,要是滿足B的話也插進去。

仔細推敲這句話!小於或等於A的以等於為準,再考慮B!就為這花了我跟師傅一上午的時間!!!

產看錶中分割槽資訊需要用到的語句

查詢父分割槽資訊

select * from USER_TAB_PARTITIONS u where u.table_name = 'MOBILEMESSAGE'
注意表名大寫
查詢子分割槽資訊
select * from USER_TAB_SUBPARTITIONS u where u.table_name = 'MOBILEMESSAGE'
目前使用分割槽就涉及了以上知識點!肯定不全面,在以後的學習中,我會繼續跟新Oracle分割槽的使用方法!!!

感謝這篇博文http://love-flying-snow.iteye.com/blog/573303,文中資料就是引用次博主