oracle间隔分区

间隔分区

范围分区允许您根据分区键列的值的范围创建分区。下面是一个按范围分区的表的示例:

 

create table sales6
(
   sales_id    number,
   sales_dt    date
)
partition by range (sales_dt)
(
   partition p0701 values less than (to_date('2007-02-01','yyyy-mm-dd')),
   partition p0702 values less than (to_date('2007-03-01','yyyy-mm-dd'))
);

 

您在此处仅针对 2007 年 1 月和 2007 年 2 月定义了分区,如果表中插入一条 sales_dt 在 2007 年 3 月的记录,会发生什么情况?插入将失败,并显示以下错误:

ORA-14400: inserted partition key does not map to any partition

 

显然,您需要针对 2007 年 3 月添加一个分区,然后才能插入一条记录。但通常说起来容易做起来难。您通常无法容忍事先创建大量分区,但其中很少一部分可能会产生此错误。

如果 Oracle 以某种方式自动察觉到对新分区的需要,然后创建它们,这样不是更好吗?Oracle Database 11g 可以,它可以使用一个称为间隔分区的特性。此时,您不必定义分区及它们的边界,只需定义 一个定义了每个分区边界的间隔。下面是使用间隔分区的示例:

create table sales6
(
   sales_id    number,
   sales_dt    date
)
partition by range (sales_dt)
                               
interval (numtoyminterval(1,'MONTH')) //number形式的使用interval(number)
(
   partition p0701 values less than (to_date('2007-02-01','yyyy-mm-dd'))
);
                            

注意子句:interval 后面跟着时间间隔。您在此处指示 Oracle 为每个月份创建一个时间间隔。您已经为 2007 年 1 月的数据创建了名为 p0701 的初始分区。现在,假设您插入了一条包括 2007 年 6 月数据的 记录:

SQL> insert into sales6 values (1,'01-jun-07');

1 row created.

 

Oracle 不会返回错误,而是成功执行该语句。那么这条记录将转向何处?p0701 分区不能包括该记录,我们没有为 2007 年 6 月定义分区。但此时,如果您检查该表的分区:

SQL> select partition_name, high_value
  2  from user_tab_partitions
  3  where table_name = 'SALES6';

PARTITION_NAME  HIGH_VALUE
---------------        ----------------------------------------------------------------
P0701           TO_DATE(' 2007-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_C
                ALENDAR=GREGORIA

SYS_P41         TO_DATE(' 2007-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_C
                ALENDAR=GREGORIA

 

注意名为 SYS_P1、高值为 2007 年 7 月 1 日的分区,它最多可以容纳到 6 月底的数据。该分区是由 Oracle 动态创建的,并具有一个系统生成的名称。

现在,假设您输入一个小于最高值的值,如 2007 年 5 月 1 日。理想情况下,它应该具有自己的分区,因 为您的分区时间间隔是一个月。

SQL> insert into sales6 values (1,'01-may-07');

1 row created.

SQL> select partition_name, high_value
  2  from user_tab_partitions
  3  where table_name = 'SALES6';

PARTITION_NAME  HIGH_VALUE
---------------        ----------------------------------------------------------------
P0701           TO_DATE(' 2007-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_C
                ALENDAR=GREGORIA

SYS_P41         TO_DATE(' 2007-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_C
                ALENDAR=GREGORIA

SYS_P42         TO_DATE(' 2007-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_C
                ALENDAR=GREGORIA

 

注意新分区 SYS_P42,其上限为 6 月 1 日,因此该分区可以保留 2006 年 5 月的数据。该分区是通过拆分 SYS_P41 分区创建的(针对 6 月份)。因此,当您定义一个间隔分区方案时,Oracle 会自动创建和维 护分区。

如果您希望将分区存储在特定表空间中,可以使用 store in 子句执行该操作:

interval (numtoyminterval(1,'MONTH'))
store in (TS1,TS2,TS3)

 

该子句以循环方式将分区存储在表空间 TS1、TS2 和 TS3 中。

应用程序开发人员如何定位特定分区?一种方法是知道名称,这种方法可能不可行,即使您知道名称,这种方法也非常容易出错。为了便于访问特定分区,Oracle Database 11g 为分区 SQL 提供了一个新 语法:

SQL> select * from sales6 partition for (to_date('15-may-2007','dd-mon-yyyy'));

  SALES_ID SALES_DT
  ----------    ---------
      1    01-MAY-07

 

注意新子句 for (值),它允许您直接引用分区,而不必通过它们的确切名称进行显式调用。如果您希望截断或删除一个分区,可以调用这个扩展的分段语法。


以此方式创建表之后,DBA_PART_TABLES 视图中的 PARTITIONING_TYPE 列会显示时间间隔。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值