Oracle表分区分为四种:范围分区,散列分区,列表分区和复合分区。
一:范围分区
就是根据数据库表中某一字段的值的范围来划分分区,例如:
按时间分区表创建
create table t_test (
pk_id number(30) not null,
add_date_time DATE,
constraintPK_T_TEST primary key (pk_id)
)
PARTITION BY RANGE (add_date_time)
(
PARTITION t_test_2013_less VALUES LESS THAN (TO_DATE('2013-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE TS_MISPS,
PARTITION t_test_2013 VALUES LESS THAN (TO_DATE('2014-01-01 00:00:00','yyyy-mm-ddhh24:mi:ss')) TABLESPACE TS_MISPS,
PARTITION t_test_2014 VALUES LESS THAN (TO_DATE('2015-01-01 00:00:00','yyyy-mm-dd hh24:mi:ss')) TABLESPACE TS_MISPS
)
按分数分区表创建
- create table graderecord
- (
- sno varchar2(10),
- sname varchar2(20),
- dormitory varchar2(3),
- grade int
- )
- partition by range(grade)
- (
- partition bujige values less than(60), --不及格
- partition jige values less than(85), --及格
- partition youxiu values less than(maxvalue) --优秀
- )
插入实验数据:
- insert into graderecord values('511601','魁','229',92);
- insert into graderecord values('511602','凯','229',62);
- insert into graderecord values('511603','东','229',26);
- insert into graderecord values('511604','亮','228',77);
- insert into graderecord values('511605','敬','228',47);
- insert into graderecord(sno,sname,dormitory) values('511606','峰','228');
- insert into graderecord values('511607','明','240',90);
- insert into graderecord values('511608','楠','240',100);
- insert into graderecord values('511609','涛','240',67);
- insert into graderecord values('511610','博','240',75);
- insert into graderecord values('511611','铮','240',60);
下面查询一下全部数据,然后查询各个分区数据,代码一起写:
- select * from graderecord;
- select * from graderecord partition(bujige);
- select * from graderecord partition(jige);
- select * from graderecord partition(youxiu);
全部数据如下:
不及格数据如下:
及格数据如下:
优秀数据如下:
说明:数据中有空值,Oracle机制会自动将其规划到maxvalue的分区中。
二:散列分区
散列分区是根据字段的hash值进行均匀分布,尽可能的实现各分区所散列的数据相等。
还是刚才那个表,只不过把范围分区改换为散列分区,语法如下(删除表之后重建):
- create table graderecord
- (
- sno varchar2(10),
- sname varchar2(20),
- dormitory varchar2(3),
- grade int
- )
- partition by hash(sno)
- (
- partition p1,
- partition p2,
- partition p3
- );
插入实验数据,与范围分区实验插入的数据相同。
然后查询分区数据:
- select * from graderecord partition(p1);
- select * from graderecord partition(p2);
- select * from graderecord partition(p3);
p1分区的数据:
p2分区的数据:
p3分区的数据:
说明:散列分区即为哈希分区,Oracle采用哈希码技术分区,具体分区如何由Oracle说的算,也可能我下一次搜索就不是这个数据了。
三:列表分区
列表分区明确指定了根据某字段的某个具体值进行分区,而不是像范围分区那样根据字段的值范围来划分的。
- create table graderecord
- (
- sno varchar2(10),
- sname varchar2(20),
- dormitory varchar2(3),
- grade int
- )
- partition by list(dormitory)
- (
- partition d229 values('229'),
- partition d228 values('228'),
- partition d240 values('240')
- )
以上根据宿舍来进行列表分区,插入与范围分区实验相同的数据,做查询如下:
- select * from graderecord partition(d229);
- select * from graderecord partition(d228);
- select * from graderecord partition(d240);
d229分区所得数据如下:
d228分区所得数据如下:
d240分区所得数据如下:
四:复合分区 (范围-散列分区,范围-列表分区)
首先讲范围-散列分区。先声明一下:列表分区不支持多列,但是范围分区和哈希分区支持多列。
代码如下:
- create table graderecord
- (
- sno varchar2(10),
- sname varchar2(20),
- dormitory varchar2(3),
- grade int
- )
- partition by range(grade)
- subpartition by hash(sno,sname)
- (
- partition p1 values less than(75)
- (
- subpartition sp1,subpartition sp2
- ),
- partition p2 values less than(maxvalue)
- (
- subpartition sp3,subpartition sp4
- )
- );
以grade划分范围,然后以sno和sname划分散列分区,当数据量大的时候散列分区则趋于“平均”。
插入数据:
- insert into graderecord values('511601','魁','229',92);
- insert into graderecord values('511602','凯','229',62);
- insert into graderecord values('511603','东','229',26);
- insert into graderecord values('511604','亮','228',77);
- insert into graderecord values('511605','敬','228',47);
- insert into graderecord(sno,sname,dormitory) values('511606','峰','228');
- insert into graderecord values('511607','明','240',90);
- insert into graderecord values('511608','楠','240',100);
- insert into graderecord values('511609','涛','240',67);
- insert into graderecord values('511610','博','240',75);
- insert into graderecord values('511611','铮','240',60);
- insert into graderecord values('511612','狸','244',72);
- insert into graderecord values('511613','杰','244',88);
- insert into graderecord values('511614','萎','244',19);
- insert into graderecord values('511615','猥','244',65);
- insert into graderecord values('511616','丹','244',59);
- insert into graderecord values('511617','靳','244',95);
查询如下:
- select * from graderecord partition(p1);
- select * from graderecord partition(p2);
- select * from graderecord subpartition(sp1);
- select * from graderecord subpartition(sp2);
- select * from graderecord subpartition(sp3);
- select * from graderecord subpartition(sp4);
分区p1数据如下,本例中75分以下:
分区p2数据如下,本例中75分之上包括75分:
子分区sp1:
子分区sp2:
子分区sp3:
子分区sp4:
说明:当数据量越来越大时,哈希分区的分区表中数据越来越趋于平衡。
下面讲范围-列表分区
范围-列表分区有两种创立方式,先说说没有模板的创建方式,这个表我要重建:
- 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')
- )
- )
插入实验数据:
- 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');
查询结果如下:
- select * from MobileMessage;
分区p1查询结果如下:
分区p2查询结果如下:
子分区xiaxun2查询结果如下:
说明:范围分区 range(A,B)的分区法则,范围分区都是 values less than(A,B)的,通常情况下以A为准,如果小于A的不用考虑B,直接插进去,如果等于A那么考虑B,要是满足B的话也插进去。
另一种范围-列表分区,包含模板的(比较繁琐,但是更加精确,处理海量存储数据十分必要):
- 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)
- );
这个是带有模板子分区的,模板子分区详细到月中的天。这种分区模式只要建立了分区就会自动创建子分区的。
插入上面不带模板分区实验相同的数据,随机查询分区数据:
查询分区p_0701_010的数据:
- select * from MobileMessage partition(p_0701_010);
查询结果:
查询子分区p_0701_010_sub4的数据:
- select * from MobileMessage subpartition(p_0701_010_sub4);
查询结果如下:
查询分区p_0706_011的数据:
- select * from MobileMessage partition(p_0706_011);
查询结果如下:
查询子分区p_0706_011_sub21的数据:
- select * from MobileMessage subpartition(p_0706_011_sub21);
查询结果如下:
下面讲讲分区的维护操作:
(1)分裂分区,以第一个范围分区为例:
- alter table graderecord split partition jige at(75)
- into(partition keyi,partition lianghao);
把分区及格分裂为两个分区:可以和良好。
(2)合并分区,以第一个范围分区为例:
- alter table graderecord merge partitions keyi,lianghao
- into partition jige;
把可以和良好两个分区合并为及格。
(3)添加分区,由于在范围分区上添加分区要求添加的分区范围大于原有分区最大值,但原有分区最大值已经为maxvalue,故本处以第二个散列分区为例:
- alter table graderecord add partition p4;
给散列分区例子又增加了一个分区p4 。
(4)删除分区,语法:
- alter table table_name drop partition partition_name;
(5)截断分区,清空分区中的数据
- alter table table_name truncate partition partition_name;
说明:对待分区的操作同样可以对待子分区,效果一样。删除一个分区会同时删除其下的子分区。合并多个分区也会把他们的子分区自动合并。分裂分区时注意分裂点。
另外不带模板子分区和带有模板子分区的分区表操作的区别:带有子分区模板的分区表在添加分区时候自动添加子分区,不带模板子分区的分区表没有这个功能;带有子分区模板的分区表在更改分区时只需更改分区,不带模板子分区的分区表在更改分区时一定注意连同子分区一起更改。