分区表主要有range、list和hash三种,翻译成中文叫范围、列表和哈希。其中列表分区是范围分区的一种特殊情况,所以这两种分区同等条件下,性能很相近。
适用场景:
range分区:如果需要进行数据的过期化,范围分区基本上是惟一的选择,例如基于日期划分分区。
hash分区:如果需要数据的均匀化分布,可以考虑哈希分区。
列表分区:如果数据的值可以很好地对应于某个分区,可以考虑列表分区,例如基于地域划分分区。
当对数据做一次分区后,分区内的数据还需要分类处理的时候,可使用组合分区。在10g中主要是支持Range-hash,Range-list两种,截止到11g,组合分区的种类有Range-hash,Range-list,Range-Range,List-Range,List-Hash,List-List。也就是支持range和list开始的任意组合分区。
各种分区表的创建例子如下:
range分区表
create table sale_range (sale_id number,sale_name varchar2(20),sale_amount number,sale_date date)
partition by range(sale_date)(
partition sale_2012_01 values less than(to_date('2012-02-01','YYYY-MM-DD')),
partition sale_2012_02 values less than(to_date('2012-03-01','YYYY-MM-DD')),
partition sale_2012_03 values less than(to_date('2012-04-01','YYYY-MM-DD')),
partition sale_2012_04 values less than(to_date('2012-05-01','YYYY-MM-DD')),
partition sale_2012_05 values less than(to_date('2012-06-01','YYYY-MM-DD')),
partition sale_2012_06 values less than(to_date('2012-07-01','YYYY-MM-DD')),
partition sale_2012_07 values less than(to_date('2012-08-01','YYYY-MM-DD')),
partition sale_2012_08 values less than(to_date('2012-09-01','YYYY-MM-DD')),
partition sale_2012_09 values less than(to_date('2012-10-01','YYYY-MM-DD')),
partition sale_2012_10 values less than(to_date('2012-11-01','YYYY-MM-DD')),
partition sale_2012_11 values less than(to_date('2012-12-01','YYYY-MM-DD')),
partition sale_2012_12 values less than(to_date('2013-01-01','YYYY-MM-DD')));
list分区表
create table product_info (id number,name varchar2(50),field varchar2(20))
partition by list(field)(
partition 华东 values('上海','浙江','江苏'),
partition 华北 values('北jing','天津','河北'),
partition 东北 values('辽宁','吉林','黑龙江'),
partition 西北 values('陕西','甘肃','新疆'),
partition 西南 values('四川','云南','西藏'),
partition 华南 values('广东','广西','贵州'));
hash分区表:
create table t_hash partition by hash(object_id) partitions 16 as select * from dba_objects;
分区表常用操作:
--删除分区
alter table emp1 drop parittion p1;
--truncate分区
alter table emp1 truncate partition p1;
--增加分区
alter table emp1 add partition dept40 values less than(40);
alter table t1 add partition p_default values less than (maxvalue); --添加缺省分区
--合并分区,除了hash以外的分区模式
alter table emp1 merge partitions DEPT10, DEPT20 into partition dept_xiao;
--收缩表分区(coalesce partitions),仅能被应用于hash分区
alter table emp2 coalesce partition;
--exchange partition分区,就是换名称而已,最大的用途把分区表变为普通表。
如果原来的表没有分区,想要变为分区表很难。字典层面的操作而已。
alter table emp1 exchange partition dept10 with table emp2 without validation;
--拆分分区
alter table emp1 split partition other at (40) into (partition dept40,partition other); --列表分区
alter table log_order split partition p_default at (to_date('2012-12-1 00:00:00','yyyy-mm-dd hh24:mi:ss')) into (partition p_2012_11,partition p_default); --范围分区
--建立分区的索引
create index iemp3 on emp1(deptno) local;
select * from user_segments where segment_name='iemp3';
select index_name,partition_name from user_ind_partitions;
alter index iemp3 rebuild partition dept20;
--不分区的索引
create index iemp2 on emp2(empno);
select * from user_segments where segment_name='iemp2';
--验证分区表相关的字典
select table_name from dict where table_name like '%part%' order by 1;
--是否是分区表和存储信息
select table_name,partitioned from user_tables where table_name='emp1';
select * from user_segments where segment_name='emp1';
col tablespace_name for a30
select segment_name,partition_name,tablespace_name from user_segments where segment_name='dr_ip_200901'
--分区表的概况
select table_name,partitioning_type, subpartitioning_type,partition_count from user_part_tables;
--详细的分区信息
select table_name,partition_name, partition_position from user_tab_partitions;
--查看每个分区的数据
select * from emp1 partition (dept10);
select * from emp1 partition (dept20);
select * from emp1 partition (other);
--将范围分区转换为interval分区
SQL> alter table sys_visit_log_his set interval (numtoyminterval(1,'month'));
组合分区创建例子:
Range-hash:
create table sale_range_hash (sale_id number,sale_name varchar2(20),sale_amount number,sale_date date)
partition by range(sale_date) subpartition by hash(sale_name)(
partition p1 values less than(to_date('2012-04-01','YYYY-MM-DD')) (subpartition sp1,subpartition sp2),
partition p2 values less than(to_date('2012-07-01','YYYY-MM-DD')) (subpartition sp3,subpartition sp4),
partition p3 values less than(to_date('2012-10-01','YYYY-MM-DD')) (subpartition sp5,subpartition sp6),
partition p4 values less than(to_date('2013-01-01','YYYY-MM-DD')) (subpartition sp7,subpartition sp8));
--做季度范围分区后,又对销售人员做了hash分区
Range-list:
create table sale_range_list (sale_id number,sale_dept varchar2(20),sale_amount number,sale_date date)
partition by range(sale_date) subpartition by list(sale_dept)(
partition p1 values less than(to_date('2012-04-01','YYYY-MM-DD'))
(subpartition sp1 values('销售一部','销售二部'),subpartition sp2 values('销售三部','销售四部')),
partition p2 values less than(to_date('2012-07-01','YYYY-MM-DD'))
(subpartition sp3 values('销售一部','销售二部'),subpartition sp4 values('销售三部','销售四部')),
partition p3 values less than(to_date('2012-10-01','YYYY-MM-DD'))
(subpartition sp5 values('销售一部','销售二部'),subpartition sp6 values('销售三部','销售四部')),
partition p4 values less than(to_date('2013-01-01','YYYY-MM-DD'))
(subpartition sp7 values('销售一部','销售二部'),subpartition sp8 values('销售三部','销售四部')));
--做季度的范围分区后,又对4个销售部门做了列表分区
RANGE-RANGE:
create table sale_range_range (sale_id number,sale_name varchar2(20),sale_amount number,sale_date date)
partition by range(sale_date) subpartition by range(sale_date)(
partition p1 values less than(to_date('2012-04-01','YYYY-MM-DD')) (
subpartition month1 values less than(to_date('2012-02-01','YYYY-MM-DD')),
subpartition month2 values less than(to_date('2012-03-01','YYYY-MM-DD')),
subpartition month3 values less than(to_date('2012-04-01','YYYY-MM-DD'))),
partition p2 values less than(to_date('2012-07-01','YYYY-MM-DD')) (
subpartition month4 values less than(to_date('2012-05-01','YYYY-MM-DD')),
subpartition month5 values less than(to_date('2012-06-01','YYYY-MM-DD')),
subpartition month6 values less than(to_date('2012-07-01','YYYY-MM-DD'))),
partition p3 values less than(to_date('2012-10-01','YYYY-MM-DD')) (
subpartition month7 values less than(to_date('2012-08-01','YYYY-MM-DD')),
subpartition month8 values less than(to_date('2012-09-01','YYYY-MM-DD')),
subpartition month9 values less than(to_date('2012-10-01','YYYY-MM-DD'))),
partition p4 values less than(to_date('2013-01-01','YYYY-MM-DD')) (
subpartition month10 values less than(to_date('2012-11-01','YYYY-MM-DD')),
subpartition month11 values less than(to_date('2012-12-01','YYYY-MM-DD')),
subpartition month12 values less than(to_date('2013-01-01','YYYY-MM-DD'))));
--先对月份做了季度分区,又对季度内每月做了月份分区
LIST-RANGE:
create table t_list_range (id number,sales_dept varchar2(50),field varchar2(20),sale_date date)
partition by list(sales_dept) subpartition by range(sale_date) (
partition p1 values('销售一部')
(subpartition sp1 values less than(to_date('2012-07-01','YYYY-MM-DD')),
subpartition sp2 values less than(to_date('2013-01-01','YYYY-MM-DD'))),
partition p2 values('销售二部')
(subpartition sp3 values less than(to_date('2012-07-01','YYYY-MM-DD')),
subpartition sp4 values less than(to_date('2013-01-01','YYYY-MM-DD'))),
partition p3 values('销售三部')
(subpartition sp5 values less than(to_date('2012-07-01','YYYY-MM-DD')),
subpartition sp6 values less than(to_date('2013-01-01','YYYY-MM-DD'))),
partition p4 values('销售四部')
(subpartition sp7 values less than(to_date('2012-07-01','YYYY-MM-DD')),
subpartition sp8 values less than(to_date('2013-01-01','YYYY-MM-DD'))));
--先对四个销售部门做了列表分区,又对每个销售部门做了半年绩效的范围分区
LIST-HASH
create table t_list_hash
partition by list(owner)
subpartition by hash(object_id)(
partition p_sys values('SYS')
(subpartition sp1,subpartition sp2,subpartition sp3,subpartition sp4),
partition p_system values('SYSTEM')
(subpartition sp5,subpartition sp6,subpartition sp7,subpartition sp8),
partition p_others values(default)
(subpartition sp9,subpartition sp10,subpartition sp11,subpartition sp12))
as select * from dba_objects;
--先对用户名做了列表分区,又对每个用户的object_id做了hash分区
LIST-LIST
create table t_list_list (id number,name varchar2(50),field varchar2(20))
partition by list(field) subpartition by list(field)(
partition 华东 values('上海','浙江')(subpartition 上海 values('上海'),subpartition 浙江 values('浙江')),
partition 华北 values('北jing','天津')(subpartition 北 values('北jing'),subpartition 天津 values('天津')),
partition 东北 values('辽宁','吉林'),
partition 西北 values('陕西','甘肃'),
partition 西南 values('四川','云南'),
partition 华南 values('广东','广西'));
--先对全国划分了6个区域,又对部分区域划分了省区域