暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

范围分区表和INTERVAL分区表相互转化

原创 yangtingkun 2020-02-07
2162

INTERVAL分区其实是一种比较特殊的范围分区,因此可以很方便的将RANGE分区表转化为INTERVAL分区表,同样可以将INTERVAL分区表转化为RANGE分区表。
对于一个普通的范围分区表:

SQL> CREATE TABLE T_PART
  2  (ID NUMBER, 
  3  NAME VARCHAR2(30), 
  4  CREATE_DATE DATE)
  5  PARTITION BY RANGE (ID) 
  6  (PARTITION P1 VALUES LESS THAN (100),
  7  PARTITION P2 VALUES LESS THAN (200),
  8  PARTITION P3 VALUES LESS THAN (300));
表已创建。
SQL> SELECT TABLE_NAME, PARTITIONING_TYPE, INTERVAL 
  2  FROM USER_PART_TABLES
  3  WHERE TABLE_NAME = 'T_PART';
TABLE_NAME                     PARTITION INTERVAL
------------------------------ --------- ----------------------------------------
T_PART                         RANGE
SQL> INSERT INTO T_PART
  2  VALUES (100, 'A', SYSDATE);
已创建 1 行。
SQL> INSERT INTO T_PART 
  2  VALUES (240, 'A', SYSDATE);
已创建 1 行。
SQL> INSERT INTO T_PART
  2  VALUES (360, 'TEST', SYSDATE);
INSERT INTO T_PART
            *
第 1 行出现错误:
ORA-14400: 插入的分区关键字未映射到任何分区

插入超过分区上限的记录会报错,下面通过一个简单ALTER TABLE语句,将RANGE分区表转化为INTERVAL分区表:

SQL> ALTER TABLE T_PART SET INTERVAL (100);
表已更改。
SQL> SELECT TABLE_NAME, PARTITIONING_TYPE, INTERVAL 
  2  FROM USER_PART_TABLES
  3  WHERE TABLE_NAME = 'T_PART';
TABLE_NAME                     PARTITION INTERVAL
------------------------------ --------- ----------------------------------------
T_PART                         RANGE     100
SQL> INSERT INTO T_PART
  2  VALUES (360, 'TEST', SYSDATE); 
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE
  2  FROM USER_TAB_PARTITIONS
  3  WHERE TABLE_NAME = 'T_PART';
TABLE_NAME                     PARTITION_NAME                 HIGH_VALUE
------------------------------ ------------------------------ ----------------------
T_PART                         P1                             100
T_PART                         P2                             200
T_PART                         P3                             300
T_PART                         SYS_P97                        400

对于INTERVAL分区表,新增的超过分区上限的数据会自动导致对应的INTERVAL分区被建立。
同样INTERVAL分区表可以方便的转化为RANGE分区表,只需要不输入INTERVAL的值即可:

SQL> ALTER TABLE T_PART SET INTERVAL ();
表已更改。
SQL> SELECT TABLE_NAME, PARTITIONING_TYPE, INTERVAL 
  2  FROM USER_PART_TABLES
  3  WHERE TABLE_NAME = 'T_PART';
TABLE_NAME                     PARTITION INTERVAL
------------------------------ --------- ----------------------------------------
T_PART                         RANGE
SQL> INSERT INTO T_PART
  2  VALUES (450, 'B', SYSDATE);
INSERT INTO T_PART
            *
第 1 行出现错误:
ORA-14400: 插入的分区关键字未映射到任何分区

同时需要注意,不输入INTERVAL的值不等价于输入NULL:

SQL> ALTER TABLE T_PART SET INTERVAL (NULL);
ALTER TABLE T_PART SET INTERVAL (NULL)
*
第 1 行出现错误:
ORA-14752: 间隔表达式不是正确类型的常数

除了RANGE分区表和INTERVAL分区表之间可以相互转化,INTERVAL分区也可以转化为RANGE分区:

SQL> ALTER TABLE T_PART SET INTERVAL (100);
表已更改。
SQL> SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE, INTERVAL
  2  FROM USER_TAB_PARTITIONS
  3  WHERE TABLE_NAME = 'T_PART';
TABLE_NAME PARTITION_NAME  HIGH_VALUE                               INTERVAL
---------- --------------- ---------------------------------------- ----------------------
T_PART     P1              100                                      NO
T_PART     P2              200                                      NO
T_PART     P3              300                                      NO
T_PART     SYS_P97         400                                      NO
SQL> INSERT INTO T_PART
  2  VALUES (453, 'A', SYSDATE);
已创建 1 行。
SQL> INSERT INTO T_PART
  2  VALUES (743, 'B', SYSDATE);
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE, INTERVAL
  2  FROM USER_TAB_PARTITIONS
  3  WHERE TABLE_NAME = 'T_PART';
TABLE_NAME PARTITION_NAME  HIGH_VALUE                               INTERVAL
---------- --------------- ---------------------------------------- --------------------
T_PART     P1              100                                      NO
T_PART     P2              200                                      NO
T_PART     P3              300                                      NO
T_PART     SYS_P97         400                                      NO
T_PART     SYS_P98         500                                      YES
T_PART     SYS_P99         800                                      YES
已选择6行。

除了MERGE PARTITION、SPLIT PARTITION之外,直接修改分区表为RANGE分区,也会使得所有现存的INTERVAL分区变成RANGE分区:

SQL> SELECT DBMS_METADATA.GET_DDL('TABLE', 'T_PART') 
  2  FROM DUAL;
DBMS_METADATA.GET_DDL('TABLE','T_PART')
--------------------------------------------------------------------------------
  CREATE TABLE "YANGTK"."T_PART"
   (    "ID" NUMBER,
        "NAME" VARCHAR2(30),
        "CREATE_DATE" DATE
   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "YANGTK"
  PARTITION BY RANGE ("ID") INTERVAL (100)
 (PARTITION "P1"  VALUES LESS THAN (100)
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE
 DEFAULT)
  TABLESPACE "YANGTK" NOCOMPRESS ,
 PARTITION "P2"  VALUES LESS THAN (200)
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "YANGTK" NOCOMPRESS ,
 PARTITION "P3"  VALUES LESS THAN (300)
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFA
ULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "YANGTK" NOCOMPRESS ,
 PARTITION "SYS_P97"  VALUES LESS THAN (400)
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT C
ELL_FLASH_CACHE DEFAULT)
  TABLESPACE "YANGTK" NOCOMPRESS )
SQL> ALTER TABLE T_PART SET INTERVAL ();
表已更改。
SQL> SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE, INTERVAL
  2  FROM USER_TAB_PARTITIONS
  3  WHERE TABLE_NAME = 'T_PART';
TABLE_NAME PARTITION_NAME  HIGH_VALUE                               INTERVAL
---------- --------------- ---------------------------------------- ----------------
T_PART     P1              100                                      NO
T_PART     P2              200                                      NO
T_PART     P3              300                                      NO
T_PART     SYS_P97         400                                      NO
T_PART     SYS_P98         500                                      NO
T_PART     SYS_P99         800                                      NO
已选择6行。
SQL> SELECT DBMS_METADATA.GET_DDL('TABLE', 'T_PART') 
  2  FROM DUAL;
DBMS_METADATA.GET_DDL('TABLE','T_PART')
--------------------------------------------------------------------------------
  CREATE TABLE "YANGTK"."T_PART"
   (    "ID" NUMBER,
        "NAME" VARCHAR2(30),
        "CREATE_DATE" DATE
   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "YANGTK"
  PARTITION BY RANGE ("ID")
 (PARTITION "P1"  VALUES LESS THAN (100)
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "YANGTK" NOCOMPRESS ,
 PARTITION "P2"  VALUES LESS THAN (200)
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT C
ELL_FLASH_CACHE DEFAULT)
  TABLESPACE "YANGTK" NOCOMPRESS ,
 PARTITION "P3"  VALUES LESS THAN (300)
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_
CACHE DEFAULT)
  TABLESPACE "YANGTK" NOCOMPRESS ,
 PARTITION "SYS_P97"  VALUES LESS THAN (400)
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE
 DEFAULT)
  TABLESPACE "YANGTK" NOCOMPRESS ,
 PARTITION "SYS_P98"  VALUES LESS THAN (500)
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFA
ULT)
  TABLESPACE "YANGTK" NOCOMPRESS ,
 PARTITION "SYS_P99"  VALUES LESS THAN (800)
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "YANGTK" NOCOMPRESS )

需要注意,INTERVAL分区在DBMS_METADATA获取的表结构中并不会出现,一旦转化为RANGE分区,则DBMS_METADATA获取的源数据会包括分区信息。

最后修改时间:2020-02-07 15:08:14
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论