(一)什么是间隔分区

间隔分区是Oracle 11.1引入的新功能,通过该功能,可以在输入相应分区的数据时自动创建相应的分区。在没有间隔分区技术之前,DBA通常会创建一个maxvalue分区以避免ORA-14400:插入的分区键值不能映射到任何分区("inserted partition key does not map to any partition") 错误。

作为范围分区(range partition)的扩展,间隔分区命令数据库在插入表中的数据超过所有现有范围分区时自动创建指定间隔的分区。DBA必须至少指定一个范围分区的较高值,称为过渡点,数据库会自动的为超出该过渡点的数据创建间隔分区,每个间隔分区的下边界是先前范围或间隔分区的上边界。

(二)创建间隔分区

(2.1)间隔分区创建语法

CREATE TABLE table_name
(
...
)
PARTITION BY RANGE(column1)
INTERVAL expr [STORE IN (tablespace1,[tablespace2,...])]
(
PARTITION partition_name1 VALUES LESS THAN(literal | MAXVALUE) [TABLESPACE tablespace1],
PARTITION partition_name2 VALUES LESS THAN(literal | MAXVALUE) [TABLESPACE tablespace2]
);

--PARTITION BY RANGE(column1):指定一个分区范围列

--INTERVAL:指定分区间隔

--STORE IN:指定分区存储的表空间

(2.2)间隔分区创建限制

间隔分区是范围分区的扩展,其支持范围有限,在Oracle 11g中,间隔分区只能指定一个分区键列,并且数据类型必须为NUMBER或者DATE类型。因为TIMESTAMP数据类型是DATE类型的扩展,可在分区键中使用。总结来说,间隔分区只支持NUMBER和TIME类型。

(2.3)INTERVAL关键字解读

在创建自动间隔分区的时候,最为核心的就是”INTERVAL“关键字了。对于按照时间进行自动分区,INTERVAL后面可以跟随NUMTOYMINTERVAL和NUMTODSINTERVAL。两个关键字用法如下:

(2.3.1)NUMTOYMINTERVAL(x,c)

用法:x是一个数据,c是一个字符串,该函数是将x转为interval year to month类型。常用单位有:”year“、”month“。

例子:当前时间加3年,当前时间加3个月

SELECT   SYSDATE,
SYSDATE + NUMTOYMINTERVAL(3,'year') AS "3年后" ,
SYSDATE + NUMTOYMINTERVAL(3,'month') AS "3个月后"
FROM dual;

(2.3.2)NUMTODSINTERVAL(x,c)

用法:x是一个数据,c是一个字符串,该函数是将x转为interval day to second类型。常用单位有:”day“、”hour“、”minute“、”second“。

例子:当前时间加1天、1小时、1分钟、1秒钟。

(三)按时间(年、月、日、周)创建间隔分区

(3.1)按”年“自动创建分区(关键字:NUMTOYMINTERVAL)

例子:创建按年自动分区表,按照员工生日(birthday字段),每年一个分区。

--创建按年分区表

CREATE TABLE interval_year_table01
(
employee_id NUMBER,
employee_name VARCHAR2(20),
birthday DATE
)
PARTITION BY RANGE(birthday)
INTERVAL (NUMTOYMINTERVAL(1,'year')) STORE IN (tbs01,tbs02,tbs03)
(
PARTITION partition2014 VALUES LESS THAN(to_date('2015-01-01:00:00:00','yyyy-mm-dd hh24:mi:ss')),
PARTITION partition2015 VALUES LESS THAN(to_date('2016-01-01:00:00:00','yyyy-mm-dd hh24:mi:ss'))
);

(3.2)按”月“自动创建分区(关键字:NUMTOYMINTERVAL)

例子:创建按月自动分区表,按照员工生日(birthday字段),每月一个分区。

-- 创建按月分区表

CREATE TABLE interval_month_table01
(
employee_id NUMBER,
employee_name VARCHAR2(20),
birthday DATE
)
PARTITION BY RANGE(birthday)
INTERVAL (NUMTOYMINTERVAL(1,'month')) STORE IN (tbs01,tbs02,tbs03)
(
PARTITION partition201401 VALUES LESS THAN(to_date('2014-02-01:00:00:00','yyyy-mm-dd hh24:mi:ss'))
);

(3.3)按”天(日)“自动创建分区(关键字:NUMTODSINTERVAL)

例子:创建按天自动分区表,按照员工生日(birthday字段),每天一个分区。

-- 按天(日)创建分区
CREATE TABLE interval_day_table01
(
employee_id NUMBER,
employee_name VARCHAR2(20),
birthday DATE
)
PARTITION BY RANGE(birthday)
INTERVAL (NUMTODSINTERVAL(1,'day')) STORE IN (tbs01,tbs02,tbs03)
(
PARTITION partition20140101 VALUES LESS THAN(to_date('2014-01-01 00:00:00','yyyy-mm-dd hh24:mi:ss'))
);

(3.4)按”周“自动创建分区(关键字:NUMTODSINTERVAL)

例子:创建按周自动分区表,按照员工生日(birthday字段),每周一个分区。需要注意的是,这里使用的关键字与“天”分区一样,都是“day”,只是改为了7天。

-- 按周创建分区

CREATE TABLE interval_week_table01
(
employee_id NUMBER,
employee_name VARCHAR2(20),
birthday DATE
)
PARTITION BY RANGE(birthday)
INTERVAL (NUMTODSINTERVAL(7,'day')) STORE IN (tbs01,tbs02,tbs03)
(
PARTITION partition201401w VALUES LESS THAN(to_date('2014-01-07 00:00:00','yyyy-mm-dd hh24:mi:ss'))
);

(3.4)按”小时“自动创建分区(关键字:NUMTODSINTERVAL)

-- 按”小时”进行分区
CREATE TABLE interval_hour_table01
(
employee_id NUMBER,
employee_name VARCHAR2(20),
birthday DATE
)
PARTITION BY RANGE(birthday)
INTERVAL (NUMTODSINTERVAL(1,'hour')) STORE IN (tbs01,tbs02,tbs03)
(
PARTITION partition20140100 VALUES LESS THAN(to_date('2014-01-01 01:00:00','yyyy-mm-dd hh24:mi:ss'))
);

除此之外,还可以按”分钟“、”秒“进行自动分区。

(四)按数字(number)创建间隔分区

例子:按数字进行分区相对简单,这里相近的10个数字进入同一个分区

CREATE TABLE interval_number_table01
(
employee_id NUMBER,
employee_name VARCHAR2(20),
birthday DATE
)
PARTITION BY RANGE(employee_id)
INTERVAL (10) STORE IN (tbs01,tbs02,tbs03)
(
PARTITION partition10 VALUES LESS THAN(10)
);

(五)关于间隔分区的常见问题

(5.1)如何将现有普通表转换为间隔分区

可以使用如下命令将现有的范围分区表转换为间隔分区表,注意,仅仅支持范围分区表:

ALTER TABLE <table_name> SET INTERVAL <number or interval expression>;

(5.2)如何为现有表设置新的间隔

可以使用如下命令修改间隔,该操作不会使index不可用:

ALTER TABLE <table_name> SET INTERVAL(interval express);

例子见MOS文档(1479115.1)。

(5.3)如何为间隔分区指定/更改表空间

INTERVAL子句的STORE IN用于指定创建间隔分区的表空间。如果指定了表空间列表,将以循环方式在这些表空间上创建间隔分区。

INTERVAL expr [STORE IN (tablespace1,[tablespace2,...])]

需要注意的是,在INTERVAL子句中使用”PARTITION“创建的范围分区需要指出表空间,否则会将范围分区创建到用户默认的表空间中,而不是[STORE IN]的表空间中。

对于已经创建的分区,可以使用以下命令将其移动到特定的表空间:

--移动分区到特定表空间
ALTER TABLE <table_name> MOVE PARTITION <partition_name> TABLESPACE <tablespace_name>; --注:移动分区会导致全局索引失效,需谨慎

(5.4)自动创建的间隔分区的名称是什么

数据库创建的间隔分区的名称是系统自动生成的,可以通过dba_tab_partition视图查看。目前无法为分区指定创建模板,但是可以重命名分区。

例子:自动创建的表空间的名称

insert into INTERVAL_NUMBER_TABLE01 values (201209, 'name09');
insert into INTERVAL_NUMBER_TABLE01 values (201210, 'name10');
insert into INTERVAL_NUMBER_TABLE01 values (201211, 'name11');
insert into INTERVAL_NUMBER_TABLE01 values (201212, 'name12');
insert into INTERVAL_NUMBER_TABLE01 values (201301, 'name01');
insert into INTERVAL_NUMBER_TABLE01 values (201402, 'name02');
insert into INTERVAL_NUMBER_TABLE01 values (201503, 'name03'); SQL> select table_owner,table_name,partition_name,high_value,tablespace_name,interval
2 from dba_tab_partitions
3 where table_name = 'INTERVAL_NUMBER_TABLE01'; TABLE_OWNER TABLE_NAME PARTITION_NAME HIGH_VALUE TABLESPACE_NAME INTERVAL
-------------- ------------------------------ ----------------- ------------ ----------------- --------
LIJIAMAN INTERVAL_NUMBER_TABLE01 PARTITION10 10 USERS NO
LIJIAMAN INTERVAL_NUMBER_TABLE01 SYS_P54 20 TBS02 YES
LIJIAMAN INTERVAL_NUMBER_TABLE01 SYS_P55 110 TBS02 YES
LIJIAMAN INTERVAL_NUMBER_TABLE01 SYS_P56 120 TBS03 YES
LIJIAMAN INTERVAL_NUMBER_TABLE01 SYS_P57 130 TBS01 YES --备注:INTERVAL = 'YES'代表自动创建的分区

(5.5)使用DBMS_METADATA.GET_DDL检索表时,为什么缺少系统生成的间隔分区?

"DBMS_METADATA.GET_DDL"只提供用户手段创建的分区,而不提供系统自动生成的分区。以下为测试例子:

SQL> SELECT DBMS_METADATA.GET_DDL('TABLE','INTERVAL_NUMBER_TABLE01','LIJIAMAN') FROM DUAL;
DBMS_METADATA.GET_DDL('TABLE',
--------------------------------------------------------------------------------
CREATE TABLE "LIJIAMAN"."INTERVAL_NUMBER_TABLE01"
( "EMPLOYEE_ID" NUMBER,
"EMPLOYEE_NAME" VARCHAR2(20),
"BIRTHDAY" DATE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS"
PARTITION BY RANGE ("EMPLOYEE_ID") INTERVAL (10) STORE IN ("TBS01", "TBS02", "TBS03")
(PARTITION "PARTITION10" VALUES LESS THAN (10) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 8388608 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" )

如果要输出系统自动创建的分区的脚本,需将DBMS_METDATA的EXPORT参数设置为true

exec dbms_metadata.set_transform_param(dbms_metadata.SESSION_TRANSFORM,'EXPORT',true);

(六)关于间隔分区的bug

以前在使用分区表时,遇到过由延迟段创建(deferred_segment_creation)引起的段分配异常问题。间隔分区也有类似的bug,使用需要谨慎。


Bug 16042673 - Database hang when system trying to add interval partition to the table (Doc ID 16042673.8)

Symptoms:
Related To:
Description

This bug is only relevant when using Partitioned Tables

Concurrent   insert   statements   issued   against  an   interval
partitioned table resulting in the creation of a new partition
blocks remaining inserts into the same table. Rediscovery Notes
If concurrent insert statements are issued against an interval
partitioned table and the insert statement which results in the
creation of a new partition blocks all the other inserts into the
table, then we might be encountering this bug.

(七)间隔分区的利弊思考

好处:间隔分区通过系统自动创建分区,减少了DBA的日常运维工作,避免了ORA-14400这类错误,每年年终不需要为下一年手动创建分区,想想还是挺开心的;

坏处:因为系统自动创建分区名称,我们无法通过分区名称来判断数据的存放位置,增加了后期的维护难度。举个例子,如果是DBA手动维护,假设表的分区”part_201901“存储的就是2019年1月的数据,假如我们想要删除1月份的数据,直接删除该分区即可,如果数据库里面有500个类似的表,直接写批量脚本”ALTER TABLE <table_name> DROP PARTITION part_201901“就将全部表的1月份的数据删除了,但是对于系统自动创建的分区,在不同的表里面,2019年1月的数据对应的分区名不同,自然无法使用脚本批量删除,即使有脚本,也非常麻烦。

-------------------------------------------------------------------------------------------------------

个人分区(partition)技术相关文档:

1. [oracle]分区表学习    
2. [Oracle]分区索引     
3. Oracle分区表删除分区引发错误ORA-01502: 索引或这类索引的分区处于不可用状态    
4. Oracle split分区表引起ORA-01502错误
5. Oracle在线重定义(online redefinition)--将普通表改为分区表

参考文档:

1. Interval Partitioning Essentials - Common Questions - Top Issues (Doc ID 1479115.1)
2. How to Build an INTERVAL PARTIONED Table using a NUMBER datatype for the INTERVAL Partition. (Doc ID 1514047.1)
3. Bug 16042673 - Database hang when system trying to add interval partition to the table (Doc ID 16042673.8)

-------------------------------------------------------------------------------------------------------

Oracle间隔(interval)分区的更多相关文章

  1. Oracle 11g 的bug?: aix 上,expdp 11.2.0.1 导出,impdp 11.2.0.3 导入,Interval 分区的 【Interval】 分区属性成了【N】

    如题: Oracle 11g 的bug?: aix 上,expdp 11.2.0.1 导出,impdp 11.2.0.3 导入,Interval 分区的 [Interval] 分区属性成了[N] 谨记 ...

  2. Oracle数据库表分区

    一.Oracle数据库表分区概念和理解         1.1.已经存在的表没有方法可以直接转化为分区表.         1.2.不在分区字段上建立分区索引,在别的字段上建立索引相当于全局索引.效率 ...

  3. 深入学习Oracle分区表及分区索引

    关于分区表和分区索引(About Partitioned Tables and Indexes)对于10gR2而言,基本上可以分成几类: •       Range(范围)分区 •       Has ...

  4. oracle 分区表和分区索引

    很复杂的样子,自己都没有看完,以备后用 http://hi.baidu.com/jsshm/item/cbfed8491d3863ee1e19bc3e ORACLE分区表.分区索引ORACLE对于分区 ...

  5. ORACLE分区表、分区索引详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt160 ORACLE分区表.分区索引ORACLE对于分区表方式其实就是将表分段 ...

  6. 【三思笔记】 全面学习Oracle分区表及分区索引

    [三思笔记]全面学习Oracle分区表及分区索引 2008-04-15 关于分区表和分区索引(About PartitionedTables and Indexes) 对于 10gR2 而言,基本上可 ...

  7. 简单ORACLE分区表、分区索引

    前一段听说CSDN.COM里面很多好东西,同事建议看看合适自己也可以写一写,呵呵,今天第一次开通博客,随便写点东西,就以第一印象分区表简单写第一个吧. ORACLE对于分区表方式其实就是将表分段存储, ...

  8. Oracle基础 表分区

    Oracle基础 表分区 一.表分区 (一)表分区的分类 1.范围分区(range) 2.散列分区(hash) 3.列表分区(list) 4.复合分区:范围-哈希(range-hash).范围-列表( ...

  9. Oracle 分区表-Range分区

    原文:http://www.tuicool.com/articles/MzeM7r 一.什么是分区表 Oracle提供了分区技术以支持VLDB(Very Large DataBase).分区表通过对分 ...

随机推荐

  1. debian8 vga 文本模式下出现闪屏

    这种问题是因为 grub 里面关于 分辨率大小不对的问题. 在 debian 里面,在文件 /boot/grub/grub.cfg 里面可以添加 vga 参数配置. 如下: 在 kernel 启动参数 ...

  2. 我最近买的书里面带的CD盘,放电脑里后,说是0字节,但是可以播放,不能把里面的东西复制出来

    我最近买的书里面带的CD盘,放电脑里后,说是0字节,但是可以播放,不能把里面的东西复制出来,有track1,track2之类的文件,都只有几十字节大,请问有没有什么方法把里面的音乐复制出来??? 用w ...

  3. IfcMaterial

    IfcMaterial is a homogeneous or inhomogeneous substance that can be used to form elements (physical ...

  4. 【jmeter】使用jmeter进行测试-示例

    介绍 jmeter主要用于负载测试,详细信息可以参见Google. 这里使用一个简单的示例,来介绍jmeter的使用. 涉及的功能点包括: HTTP HEADER配置 HTTP Request配置 J ...

  5. 利用nvidia-smi 管理和监控NVIDIA GPU设备

    NVIDIA系统管理界面介绍 原文来源:https://developer.nvidia.com/nvidia-system-management-interface NVIDIA系统管理界面(nvi ...

  6. android文件分享在android7.0以上版本报错的解决方案

    最近在使用蓝牙进行文件分享时,出现了一个奇怪的问题.同样的代码在android5.1上可以顺利运行,但是在android7.0上就运行失败.出现如下的错误: Caused by: android.os ...

  7. javascript之this、new、apply和call详解

    this指针的原理是个很复杂的问题,如果我们从javascript里this的实现机制来说明this,很多朋友可能会越来越糊涂,因此本篇打算换一个思路从应用的角度来讲解this指针,从这个角度理解th ...

  8. Visual Studio 2017 Add WSDL

    Normal way Right click Project -> Add -> Web Reference -> Advanced Intranet way download ws ...

  9. Vue 动态路由的实现以及 Springsecurity 按钮级别的权限控制

    思路: 动态路由实现:在导航守卫中判断用户是否有用户信息,通过调用接口,拿到后台根据用户角色生成的菜单树,格式化菜单树结构信息并递归生成层级路由表并使用Vuex保存,通过 router.addRout ...

  10. js中对字符串操作的常见方法(1)

    String类型 创建一个String类型的实例 var stringObject = new String("hello world"); String类型的属性 length; ...