Oracle11g中推出的Interval-Partition特性,是针对Range类型分区的一种功能拓展。对连续数据类型的Range分区,如果插入的新数据值与当前分区均不匹配,Interval-Partition特性可以实现自动的分区创建。
目前的Interval-Partition支持的Range分区键类型只有number和date两种类型。在上面的示例中,我们已经演示了数字number类型的分区拓展,下面我们进行date类型演示。
1、Interval-Partition forDateRange
笔者认为,相对于number类型的分区拓展,date类型interval-partition分区的应用空间更为广泛。因为实际生产环境下使用某个特定日期范围分区的场景非常多,比如特定年度的交易作为单独分区。
同样选择Oracle 11R2的scott用户schema作为实验环境。
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------
Oracle Database11gEnterpriseEdition Release11.2.0.1.0 - Production
PL/SQL Release11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version11.2.0.1.0 - Production
NLSRTL Version11.2.0.1.0 - Production
SQL> conn scott/tiger@wilson ;
Connected to Oracle Database11gEnterpriseEdition Release11.2.0.1.0
Connected as scott
SQL> select DEFAULT_TABLESPACE, TEMPORARY_TABLESPACE from dba_users where username='SCOTT';
DEFAULT_TABLESPACE TEMPORARY_TABLESPACE
------------------------------ ------------------------------
USERS TEMP
我们利用dba_objects数据视图创建分区表,使用last_ddl_time作为分区键。
SQL> create table t_part
2 partition by range(last_ddl_time)
3 interval (numtoyminterval(1,'year'))
4 (
5 partition p1 values less than (to_date('2003-1-1','yyyy-mm-dd'))
6 )
7 as
8 select * from dba_objects where 1=0;
Table created
处理中间的interval(numtoyminterval(1,’year’)),该数据表和其他日期类型分区数据表没有差异。Numtoyminterval表示使用年作为时间间隔,每一年作为一个分区间距。
同时,在定义数据表的时候,定义了一个保存2003年之前所有数据的分区p1。此时,我们观察数据字典情况。
SQL> select segment_name, partition_name,SEGMENT_TYPE, tablespace_name from user_segments where segment_name='T_PART';
SEGMENT_NA PARTITION_ SEGMENT_TYPE TABLESPACE_NAME
---------- ---------- ------------------ ------------------------------
T_PART P1 TABLE PARTITION USERS
SQL> select table_name, partition_name, high_value, tablespace_name from user_tab_partitions where table_name='T_PART';
TABLE_NAME PARTITION_ HIGH_VALUE TABLESPACE_NAME
---------- ---------- -------------------- ------------------------------
T_PART P1 TO_DATE('2003-01-01USERS
00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'N
LS_CALENDAR=GREGORIA
分区p1为预定义分区。此时我们向其中插入数据。
SQL> insert into t_part select * from dba_objects where last_ddl_time<to_date('2003-1-1','yyyy-mm-dd');
3 rows inserted
SQL> insert into t_part select * from dba_objects where last_ddl_time>to_date('2003-1-1','yyyy-mm-dd');
72599 rows inserted
SQL> commit;
Commit complete
此时,其中插入的数据已经与原有分区不匹配了。
SQL> exec dbms_stats.gather_table_stats(user,'T_PART',cascade => true);
PL/SQL procedure successfully completed
SQL> select table_name, partition_name, high_value, tablespace_name, num_rows from user_tab_partitions where table_name='T_PART';
TABLE_NAME PARTITION_ HIGH_VALUE TABLESPACE_NAME NUM_ROWS
---------- ---------- -------------------- ------------------------------ ----------
T_PART P1 TO_DATE('2003-01-01USERS 3
00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'N
LS_CALENDAR=GREGORIA
T_PART SYS_P24 TO_DATE('2009-01-01USERS 1
00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'N
LS_CALENDAR=GREGORIA
T_PART SYS_P21 TO_DATE('2010-01-01USERS 71678
00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'N
LS_CALENDAR=GREGORIA
T_PART SYS_P22 TO_DATE('2011-01-01USERS 711
00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'N
LS_CALENDAR=GREGORIA
T_PART SYS_P23 TO_DATE('2012-01-01USERS 209
00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'N
LS_CALENDAR=GREGORIA
结论:对于date类型分区键的interval-partition分区表,当不符合分区条件的记录,会自动生成分区进行保存。
另外,如果要求对每周的数据划分为分区,可以使用numtodsinterval函数。
INTERVAL(numtodsinterval(7,'day'))
2、Partition Tablespace
分区表的创建目的,除了进行分区内局部扫描、便于管理外,还可以通过将分区存放在不同的表空间做到平衡分散IO的目的。所以,对分区的表空间规划,通常是DBA日常决策的一个重要内容。
在interval-partition中,分区的创建不是预创建过程,而是系统自动生成。那么,表空间storage如何规划设计呢?
从上面的t_part数据分区表中,无论是数据表体,还是各个分区,都没有显示的指明数据分区的表空间存储。从结果看,保存的位置都是users表空间,而users表空间是用户scott的默认表空间。
SQL> select DEFAULT_TABLESPACE, TEMPORARY_TABLESPACE from dba_users where username='SCOTT';
DEFAULT_TABLESPACE TEMPORARY_TABLESPACE
------------------------------ ------------------------------
USERS TEMP
说明:如果分区���没有明确表示使用的分区表空间,Oracle会选择用户schema对应的表空间作为分区所在表空间。
如果进行部分执行表空间的工作,会如何呢?
首先,调整scott用户对应的default tablespace。
SQL> select DEFAULT_TABLESPACE, TEMPORARY_TABLESPACE from dba_users where username='SCOTT';
DEFAULT_TABLESPACE TEMPORARY_TABLESPACE
------------------------------ ------------------------------
SYSTEM TEMP
进行分区表创建。
SQL> create table t_part
2 partition by range(sal)
3 interval (1000)
4 (
5 partition p1 values less than (1000),
6 partition p2 values less than (2000)tablespace SYSAUX
7 )
8 as
9 select * from emp where sal<2000;
Table created
SQL> select segment_name, partition_name,SEGMENT_TYPE, tablespace_name from user_segments where segment_name='T_PART';
SEGMENT_NA PARTITION_ SEGMENT_TYPE TABLESPACE_NAME
---------- ---------- ------------------ ------------------------------
T_PART P1 TABLE PARTITION SYSTEM
T_PART P2 TABLE PARTITION SYSAUX
在没有使用store in的情况下,我们可以使用tablespace关键字对特殊分区进行指定。如果没有指定,则选择用户默认表空间。
SQL> insert into t_part select * from emp where sal>=2000;
6 rows inserted
SQL> commit;
Commit complete
SQL> select segment_name, partition_name,SEGMENT_TYPE, tablespace_name from user_segments where segment_name='T_PART';
SEGMENT_NA PARTITION_ SEGMENT_TYPE TABLESPACE_NAME
---------- ---------- ------------------ ------------------------------
T_PART P1 TABLE PARTITION SYSTEM
T_PART P2 TABLE PARTITION SYSAUX
T_PART SYS_P25 TABLE PARTITION SYSTEM
T_PART SYS_P26 TABLE PARTITION SYSTEM
T_PART SYS_P27 TABLE PARTITION SYSTEM