Oracle原理:表分區

目錄

1.範圍分區、散列分區、列表分區、複合分區。

2.11g新增的引用分區、間隔分區、基於虛擬列的分區、系統分區。


1.範圍分區、散列分區、列表分區、複合分區。

允許用戶將一個表分成多個區,用戶可以執行查詢時,只訪問表中的特定分區;將不同的分區存儲在不同的磁盤,提高訪問性能和安全性;並且可以獨立的備份和恢復每個分區;SQLSever2005有了分區表內容,但是建分區表時比較麻煩,Oracle建分區表相比比較簡單。和索引相比都是爲了提高查詢速度,但是分區是物理上的,因爲在做增刪查改時,數據庫會根據 where 後面的篩選條件來進行遍歷,普通表遍歷時會從零號數據塊遍歷到高水位線。但是有了表分區後,可以快速鎖定數據內存的位置範圍,在範圍中進行遍歷,大大加快了查詢速度。

分區方法4種:

範圍分區:表中的一列或者多列進行範圍分區

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'); --彙報無法映射到任何分區的錯誤
commit;

按分區查找信息:

select * from student partition(s1) where sname='A';

查詢分區信息:

select * from user_tab_partitions where table_name ='STUDENT';
在範圍分區中,會根據某個字段(entrance_date)的值進行判斷該放入哪一塊分區中,s1分區爲2015-7-1之前的,不包含當天,s2,從2015-7-1 當天 到2016-7-1 之前 ,超出分區範圍的數據是沒有辦法插入的,要添加分區外的數據只能先添加分區。

alter table student add partition s5 values less than(maxvalue);
insert into student values(5,date'2019-5-30','A');

散列分區:當數據字段沒有什麼邏輯關係時,可以考慮散列分區。散列分區會把數據分散分配到各個區中,採用HASH函數決定了存儲數據到哪塊分區上。這樣分區內的數據量就比較平均。hash分區的hash函數無法自定義,由Oracle 自動提供。

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;

 

列表分區:

和範圍分區類似,當字段的取值是一個範圍時,可以採用範圍分區;當字段的取值是個枚舉時,可以採用列表分區。例如像所在省份 這樣的字段,就相比範圍分區更適合用列表分區。 

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;

同樣的,插入不在分區範圍的數據時,會報錯。

複合分區:

就是範圍分區和散列分區結合  或者 列表分區和散列分區相結合的分區。 此時的散列分區只能做範圍分區和列表分區的子分區。

create table student_range_hash(
sno int,
entrance_date date,
address varchar2(20)
)
partition by range(entrance_date)
subpartition by hash(sno)   --子分區hash(sno)
subpartitions 4   --指明每個範圍分區中有4個hash分區
(
  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)
);

查看分區信息 和查看子分區信息:

select * from user_tab_partitions where table_name ='STUDENT_RANGE_HASH';
select * from user_tab_subpartitions where table_name ='STUDENT_RANGE_HASH';

2.11g新增的引用分區、間隔分區、基於虛擬列的分區、系統分區。

引用分區:一定要有個主鍵和外鍵之間的關係。外鍵表可以繼承父表的分區方式,而不用自己新建。

----------創建主表--------
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;
----------副表創建 (設立主鍵,設立外鍵)---------
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);   ---引用分區關聯外鍵

select * from user_tab_partitions where table_name ='STUDENT_HASH' or table_name ='SCORE_POINTER';

在引用分區中,副表的分區字段屬性和主表的分區字段的屬性一樣。主表用了散列分區,那麼副表就用散列分區,使用的hash函數和主表是一致的;如果主要用了範圍分區,那麼分區的類型和分區的取值範圍主表和副表都是一致的。

 

間隔分區:

完全自動根據 間隔閾值 來創建範圍分區。是範圍分區的擴展。間隔分區屬於範圍分區。在範圍分區中,當每次輸入的值超出分區範圍時,就會報錯,而間隔分區會新建分區自動擴展 可輸入的範圍。自動擴展多大呢?自動擴展的大小就是間隔閾值。

create table student(
sno int,
entrance_date date,
sname varchar2(20)
)
partition by range(entrance_date)
interval ( numtoyminterval(1,'MONTH') ) --每超出最大範圍一個月自動創建一個分區。
(
  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');
insert into student values(5,date'2021-5-30','A');
commit;

select * from user_tab_partitions where table_name ='STUDENT' 

剛開始初始化了4個分區,當插入entrance_date=date'2019-5-30'時就會創建一個從 2019-5-1 到2019-6-1的分區;當插入entrance_date=date'2021-5-30'時就會創建一個從 2021-5-1 到2021-6-1的分區,。分區範圍爲分區閾值所指定的1個月。從初始化的分區範圍最大值2018-7-1開始分,連續一個月一個月的加。

基於虛擬列的分區:範圍分區、散列分區、列表分區等可以作用在虛擬列上的。分區原理和傳統分區沒區別。

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
);

系統分區:不需要指定分區列,不需要範圍等,只需要指定分區的個數就行,一切分區的控制和管理由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
);

 

 

操作分區時,和查找普通表是完全相同,Oracle會自動把數據保存到對應的分區上,刪除的時候也會自動地找到相應的分區把數據刪除。增刪查改語句時可以 顯示指定要操作的分區。

添加/刪除/截斷分區:

ALTER TABLE [tablename]   ADD /DROP /TRUNCATE     PARTITION  [partitionName] ;

 

合併分區:在分區相鄰的情況下可以進行分區合併:

ALTER TABLE [tablename]  MERGE PARTITIONS [分區名1],[分區名2]  INTO PARTITION [新分區名];

拆分分區: 適用於分區類型爲範圍分區的拆分。

ALTER TABLE [tablename]  SPLIT PARTITION [分區名] 

AT(拆分的臨界點)  

INTO  (   PARTITION [新分區名1]  , PARTITION [新分區名2] );

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章