Oracle原理:表分区
目錄
1.范圍分區(qū)、散列分區(qū)、列表分區(qū)、復(fù)合分區(qū)。
2.11g新增的引用分區(qū)、間隔分區(qū)、基于虛擬列的分區(qū)、系統(tǒng)分區(qū)。
1.范圍分區(qū)、散列分區(qū)、列表分區(qū)、復(fù)合分區(qū)。
允許用戶將一個(gè)表分成多個(gè)區(qū),用戶可以執(zhí)行查詢時(shí),只訪問表中的特定分區(qū);將不同的分區(qū)存儲(chǔ)在不同的磁盤,提高訪問性能和安全性;并且可以獨(dú)立的備份和恢復(fù)每個(gè)分區(qū);SQLSever2005有了分區(qū)表內(nèi)容,但是建分區(qū)表時(shí)比較麻煩,Oracle建分區(qū)表相比比較簡(jiǎn)單。和索引相比都是為了提高查詢速度,但是分區(qū)是物理上的,因?yàn)樵谧鲈鰟h查改時(shí),數(shù)據(jù)庫(kù)會(huì)根據(jù) where 后面的篩選條件來進(jìn)行遍歷,普通表遍歷時(shí)會(huì)從零號(hào)數(shù)據(jù)塊遍歷到高水位線。但是有了表分區(qū)后,可以快速鎖定數(shù)據(jù)內(nèi)存的位置范圍,在范圍中進(jìn)行遍歷,大大加快了查詢速度。
分區(qū)方法4種:
范圍分區(qū):表中的一列或者多列進(jìn)行范圍分區(qū)
create table student( sno int, entrance_date date, sname varchar2(20) ) partition by range(entrance_date)(partition s1 values less than (date'2015-7-1'),partition s2 values less than (date'2016-7-1'),partition s3 values less than (date'2017-7-1'),partition s4 values less than (date'2018-7-1') ); insert into student values(1,date'2015-5-30','A'); insert into student values(2,date'2015-7-1','B'); insert into student values(3,date'2016-7-1','A'); insert into student values(4,date'2018-1-30','A'); --insert into student values(5,date'2019-5-30','A'); --匯報(bào)無法映射到任何分區(qū)的錯(cuò)誤 commit;按分區(qū)查找信息:
select * from student partition(s1) where sname='A';
查詢分區(qū)信息:
select * from user_tab_partitions where table_name ='STUDENT';
在范圍分區(qū)中,會(huì)根據(jù)某個(gè)字段(entrance_date)的值進(jìn)行判斷該放入哪一塊分區(qū)中,s1分區(qū)為2015-7-1之前的,不包含當(dāng)天,s2,從2015-7-1 當(dāng)天 到2016-7-1 之前 ,超出分區(qū)范圍的數(shù)據(jù)是沒有辦法插入的,要添加分區(qū)外的數(shù)據(jù)只能先添加分區(qū)。
散列分區(qū):當(dāng)數(shù)據(jù)字段沒有什么邏輯關(guān)系時(shí),可以考慮散列分區(qū)。散列分區(qū)會(huì)把數(shù)據(jù)分散分配到各個(gè)區(qū)中,采用HASH函數(shù)決定了存儲(chǔ)數(shù)據(jù)到哪塊分區(qū)上。這樣分區(qū)內(nèi)的數(shù)據(jù)量就比較平均。hash分區(qū)的hash函數(shù)無法自定義,由Oracle 自動(dòng)提供。
create table student_hash( sno int, entrance_date date, sname varchar2(20) ) partition by HASH(sno)(partition s1 ,partition s2 ); insert into student_hash values(1,date'2015-5-30','A'); insert into student_hash values(2,date'2015-7-1','B'); insert into student_hash values(3,date'2016-7-1','A'); insert into student_hash values(4,date'2018-1-30','A'); commit;?
列表分區(qū):
和范圍分區(qū)類似,當(dāng)字段的取值是一個(gè)范圍時(shí),可以采用范圍分區(qū);當(dāng)字段的取值是個(gè)枚舉時(shí),可以采用列表分區(qū)。例如像所在省份 這樣的字段,就相比范圍分區(qū)更適合用列表分區(qū)。?
create table student_list( sno int, entrance_date date, address varchar2(20) ) partition by LIST(address)(partition 東南沿海 values ('福建','廣東','浙江'),partition 東北 values ('黑龍江','遼寧','吉林'),partition 西部 values ('西藏','新疆') ); insert into student_list values(1,date'2015-5-30','福建'); insert into student_list values(2,date'2015-7-1','廣東'); insert into student_list values(3,date'2016-7-1','西藏'); --insert into student_list values(4,date'2018-1-30','湖北'); commit;同樣的,插入不在分區(qū)范圍的數(shù)據(jù)時(shí),會(huì)報(bào)錯(cuò)。
復(fù)合分區(qū):
就是范圍分區(qū)和散列分區(qū)結(jié)合? 或者 列表分區(qū)和散列分區(qū)相結(jié)合的分區(qū)。 此時(shí)的散列分區(qū)只能做范圍分區(qū)和列表分區(qū)的子分區(qū)。
create table student_range_hash( sno int, entrance_date date, address varchar2(20) ) partition by range(entrance_date) subpartition by hash(sno) --子分區(qū)hash(sno) subpartitions 4 --指明每個(gè)范圍分區(qū)中有4個(gè)hash分區(qū) (partition s1 values less than (date'2015-7-1'),partition s2 values less than (date'2016-7-1'),partition s3 values less than (date'2017-7-1'),partition s4 values less than (date'2018-7-1'),partition s5 values less than (maxvalue) );查看分區(qū)信息 和查看子分區(qū)信息:
select * from user_tab_partitions where table_name ='STUDENT_RANGE_HASH'; select * from user_tab_subpartitions where table_name ='STUDENT_RANGE_HASH';2.11g新增的引用分區(qū)、間隔分區(qū)、基于虛擬列的分區(qū)、系統(tǒng)分區(qū)。
引用分區(qū):一定要有個(gè)主鍵和外鍵之間的關(guān)系。外鍵表可以繼承父表的分區(qū)方式,而不用自己新建。
----------創(chuàng)建主表-------- create table student_hash( sno int primary key, entrance_date date, sname varchar2(20) ) partition by HASH(sno)(partition s1 ,partition s2 ); insert into student_hash values(1,date'2015-5-30','A'); insert into student_hash values(2,date'2015-7-1','B'); insert into student_hash values(3,date'2016-7-1','A'); insert into student_hash values(4,date'2018-1-30','A'); commit; ----------副表創(chuàng)建 (設(shè)立主鍵,設(shè)立外鍵)--------- create table score_pointer( exam_id int primary key, sno int not null, score int, constraint fk_score foreign key(sno) references student_hash(sno) ) partition by reference(fk_score); ---引用分區(qū)關(guān)聯(lián)外鍵select * from user_tab_partitions where table_name ='STUDENT_HASH' or table_name ='SCORE_POINTER';
在引用分區(qū)中,副表的分區(qū)字段屬性和主表的分區(qū)字段的屬性一樣。主表用了散列分區(qū),那么副表就用散列分區(qū),使用的hash函數(shù)和主表是一致的;如果主要用了范圍分區(qū),那么分區(qū)的類型和分區(qū)的取值范圍主表和副表都是一致的。
?
間隔分區(qū):
完全自動(dòng)根據(jù) 間隔閾值 來創(chuàng)建范圍分區(qū)。是范圍分區(qū)的擴(kuò)展。間隔分區(qū)屬于范圍分區(qū)。在范圍分區(qū)中,當(dāng)每次輸入的值超出分區(qū)范圍時(shí),就會(huì)報(bào)錯(cuò),而間隔分區(qū)會(huì)新建分區(qū)自動(dòng)擴(kuò)展 可輸入的范圍。自動(dòng)擴(kuò)展多大呢?自動(dòng)擴(kuò)展的大小就是間隔閾值。
create table student( sno int, entrance_date date, sname varchar2(20) ) partition by range(entrance_date) interval ( numtoyminterval(1,'MONTH') ) --每超出最大范圍一個(gè)月自動(dòng)創(chuàng)建一個(gè)分區(qū)。 (partition s1 values less than (date'2015-7-1'), -----初始化分區(qū)partition s2 values less than (date'2016-7-1'), partition s3 values less than (date'2017-7-1'),partition s4 values less than (date'2018-7-1') ); insert into student values(1,date'2015-5-30','A'); insert into student values(2,date'2015-7-1','B'); insert into student values(3,date'2016-7-1','A'); insert into student values(4,date'2018-1-30','A'); insert into student values(5,date'2019-5-30','A'); insert into student values(5,date'2021-5-30','A'); commit;select * from user_tab_partitions where table_name ='STUDENT'?
剛開始初始化了4個(gè)分區(qū),當(dāng)插入entrance_date=date'2019-5-30'時(shí)就會(huì)創(chuàng)建一個(gè)從 2019-5-1 到2019-6-1的分區(qū);當(dāng)插入entrance_date=date'2021-5-30'時(shí)就會(huì)創(chuàng)建一個(gè)從 2021-5-1 到2021-6-1的分區(qū),。分區(qū)范圍為分區(qū)閾值所指定的1個(gè)月。從初始化的分區(qū)范圍最大值2018-7-1開始分,連續(xù)一個(gè)月一個(gè)月的加。
基于虛擬列的分區(qū):范圍分區(qū)、散列分區(qū)、列表分區(qū)等可以作用在虛擬列上的。分區(qū)原理和傳統(tǒng)分區(qū)沒區(qū)別。
create table score( exam_id int primary key, sno int not null, score int, score_percent as (score /150.0 * 100.0) virtual ---指明虛擬列 ) partition by HASH(score_percent)(partition s1 ,partition s2 );系統(tǒng)分區(qū):不需要指定分區(qū)列,不需要范圍等,只需要指定分區(qū)的個(gè)數(shù)就行,一切分區(qū)的控制和管理由Oracle來完成。
create table score2( exam_id int primary key, sno int not null, score int, score_percent as (score /150.0 * 100.0) virtual ) partition by system(partition s1 ,partition s2 );?
?
操作分區(qū)時(shí),和查找普通表是完全相同,Oracle會(huì)自動(dòng)把數(shù)據(jù)保存到對(duì)應(yīng)的分區(qū)上,刪除的時(shí)候也會(huì)自動(dòng)地找到相應(yīng)的分區(qū)把數(shù)據(jù)刪除。增刪查改語句時(shí)可以 顯示指定要操作的分區(qū)。
添加/刪除/截?cái)喾謪^(qū):
ALTER TABLE [tablename]? ?ADD /DROP /TRUNCATE? ? ?PARTITION? [partitionName] ;
?
合并分區(qū):在分區(qū)相鄰的情況下可以進(jìn)行分區(qū)合并:
ALTER TABLE [tablename]? MERGE PARTITIONS [分區(qū)名1],[分區(qū)名2]? INTO PARTITION [新分區(qū)名];
拆分分區(qū): 適用于分區(qū)類型為范圍分區(qū)的拆分。
ALTER TABLE [tablename]? SPLIT?PARTITION?[分區(qū)名]?
AT(拆分的臨界點(diǎn))??
INTO? (? ?PARTITION?[新分區(qū)名1]? , PARTITION [新分區(qū)名2] );
總結(jié)
以上是生活随笔為你收集整理的Oracle原理:表分区的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle 原理:高水位线、PCTFR
- 下一篇: Oracle 原理: 公有同义词 和 私