在使用范围分区表的时候,尤其是建立一个以时间进行分区的分区表,感觉最麻烦的事情就是需要不断的ADD或者SPLIT新的分区。
无论是手工进行这个操作还是通过写PL/SQL来执行,都是比较麻烦的事情。
在11g中,Oracle把这个麻烦解决掉了,新增的INTERVAL功能,可以在需要的时候自动的添加新的分区。
看一个简单的例子:
SQL> CREATE TABLE T_INTERVAL
2 PARTITION BY RANGE (CREATED)
3 INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'))
4 (PARTITION P1 VALUES LESS THAN (TO_DATE('2007-9-1', 'YYYY-MM-DD')))
5 AS SELECT * FROM DBA_OBJECTS;
表已创建。
SQL> SELECT TO_CHAR(MAX(CREATED), 'YYYY-MM-DD HH24:MI:SS') FROM T_INTERVAL;
TO_CHAR(MAX(CREATED
-------------------
2007-10-10 05:01:57
在建立分区表的时候只指定了一个分区,上限为9月1日,但是数据的最大值已经达到了10月10日,Oracle这里自动创建了两个分区:
SQL> SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE FROM USER_TAB_PARTITIONS
2 WHERE TABLE_NAME = 'T_INTERVAL'
3 ORDER BY 2;
TABLE_NAME PARTITION_NAME HIGH_VALUE
---------- -------------- --------------------------------------------------------------------------
T_INTERVAL P1 TO_DATE(' 2007-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
T_INTERVAL SYS_P63 TO_DATE(' 2007-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORI
T_INTERVAL SYS_P64 TO_DATE(' 2007-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORI
使用INTERVAL分区,可以不再为分区的增长而发愁。而且,只需要执行普通的DML语句,Oracle会自动维护分区,不在需要发出DDL语句,也不会由于DDL影响到索引的状态:
SQL> CREATE INDEX IND_INTERVAL_OWNER ON T_INTERVAL(OWNER) LOCAL;
索引已创建。
SQL> CREATE INDEX IND_INTERVAL_OBJECTNAME ON T_INTERVAL(OBJECT_NAME);
索引已创建。
SQL> INSERT INTO T_INTERVAL (OWNER, OBJECT_NAME, CREATED)
2 VALUES (USER, 'TEST', SYSDATE + 30);
已创建 1 行。
SQL> SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE FROM USER_TAB_PARTITIONS
2 WHERE TABLE_NAME = 'T_INTERVAL'
3 ORDER BY 2;
TABLE_NAME PARTITION_NAME HIGH_VALUE
---------- -------------- --------------------------------------------------------------------------
T_INTERVAL P1 TO_DATE(' 2007-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
T_INTERVAL SYS_P63 TO_DATE(' 2007-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORI
T_INTERVAL SYS_P64 TO_DATE(' 2007-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORI
T_INTERVAL SYS_P74 TO_DATE(' 2007-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORI
SQL> SELECT STATUS FROM USER_INDEXES WHERE TABLE_NAME = 'T_INTERVAL';
STATUS
--------
VALID
N/A
SQL> SELECT INDEX_NAME, STATUS FROM USER_INDEXES WHERE TABLE_NAME = 'T_INTERVAL';
INDEX_NAME STATUS
------------------------------ --------
IND_INTERVAL_OBJECTNAME VALID
IND_INTERVAL_OWNER N/A
SQL> SELECT INDEX_NAME, PARTITION_NAME, STATUS FROM USER_IND_PARTITIONS
2 WHERE INDEX_NAME = 'IND_INTERVAL_OWNER';
INDEX_NAME PARTITION_NAME STATUS
------------------------------ -------------- --------
IND_INTERVAL_OWNER P1 USABLE
IND_INTERVAL_OWNER SYS_P72 USABLE
IND_INTERVAL_OWNER SYS_P73 USABLE
IND_INTERVAL_OWNER SYS_P74 USABLE
最后看一个NUMBER类型INTERVAL的例子:
SQL> CREATE TABLE T_INTERVAL_NUMBER
2 PARTITION BY RANGE (ID)
3 INTERVAL (10000)
4 (PARTITION P1 VALUES LESS THAN (10000))
5 AS SELECT ROWNUM ID, A.* FROM DBA_OBJECTS A;
表已创建。
SQL> SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE FROM USER_TAB_PARTITIONS
2 WHERE TABLE_NAME = 'T_INTERVAL_NUMBER'
3 ORDER BY 2;
TABLE_NAME PARTITION_NAME HIGH_VALUE
-------------------- -------------- -------------------------------------------------------
T_INTERVAL_NUMBER P1 10000
T_INTERVAL_NUMBER SYS_P75 20000
T_INTERVAL_NUMBER SYS_P76 30000
T_INTERVAL_NUMBER SYS_P77 40000
T_INTERVAL_NUMBER SYS_P78 50000
T_INTERVAL_NUMBER SYS_P79 60000
T_INTERVAL_NUMBER SYS_P80 70000
已选择7行。
由于其他数据类型没有INTERVAL的概念,因此INTERVAL分区只支持NUMBER和DATE类型。
阅读(233) | 评论(0) | 转发(0) |