设为首页 收藏本站
查看: 862|回复: 0

[经验分享] Oracle 11g 新特性:自动创建分区(Interval Partition)

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-12-1 09:02:34 | 显示全部楼层 |阅读模式
分区(Partition)一直是Oracle数据库引以为傲的一项技术,正是分区的存在让Oracle高效的处理海量数据成为可能,在Oracle 11g中,分区技术在易用性和可扩展性上再次得到了增强。在10g的Oracle版本中,要对分区表做调整,尤其是对RANGE分区添加新的分区都需要DBA手动定期添加,或都使用存储过程进行管理。在11G的版本中的Interval Partition不再需要DBA去干预新分区的添加,Oracle会自动去执行这样的操作,减少了DBA的工作量。Interval Partition是Range分区的一个扩展。 使用Interval Partition也有一些限制:

  • You can only specify one partitioning key column, and it must be of NUMBER or DATE type.
  • Interval partitioning is not supported for index-organized tables.
  • You cannot create a domain index on an interval-partitioned table.

Interval Partition也可以创建复合分区:

  • Interval-range
  • Interval-hash
  • Interval-list

创建Interval分区表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sys@ORCL>CREATE TABLE interval_sales
  2      ( prod_id        NUMBER(6)
  3      , cust_id        NUMBER
  4      , time_id        DATE
  5      , channel_id     CHAR(1)
  6      , promo_id       NUMBER(6)
  7      , quantity_sold  NUMBER(3)
  8      , amount_sold    NUMBER(10,2)
  9      )
10    PARTITION BY RANGE (time_id)
11    INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
12      ( PARTITION p0 VALUES LESS THAN (TO_DATE('1-1-2008', 'DD-MM-YYYY')),
13        PARTITION p1 VALUES LESS THAN (TO_DATE('1-1-2009', 'DD-MM-YYYY')),
14        PARTITION p2 VALUES LESS THAN (TO_DATE('1-7-2009', 'DD-MM-YYYY')),
15        PARTITION p3 VALUES LESS THAN (TO_DATE('1-1-2010', 'DD-MM-YYYY')) );

Table created.



插入在指定分区范围内的测试数据,数据插入成功

1
2
3
4
5
6
7
8
9
10
11
12
13
sys@ORCL>insert into interval_sales values(1,101,to_date('2008-06-01','yyyy-mm-dd'),'a',201,101,10);

1 row created.

sys@ORCL>commit;

Commit complete.

sys@ORCL>select * from interval_sales partition(p1);

   PROD_ID    CUST_ID TIME_ID             CHA   PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- ------------------- --- ---------- ------------- -----------
         1        101 2008-06-01 00:00:00 a          201           101          10



插入不在指定分区范围内的测试数据,数据插入成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sys@ORCL>insert into interval_sales values(2,101,to_date('2010-01-03','yyyy-mm-dd'),'a',201,101,10);

1 row created.

sys@ORCL>commit;

Commit complete.

sys@ORCL>select * from interval_sales;

   PROD_ID    CUST_ID TIME_ID             CHA   PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- ------------------- --- ---------- ------------- -----------
         1        101 2008-06-01 00:00:00 a          201           101          10
         2        101 2010-01-03 00:00:00 a          201           101          10



查看现在表的所有分区
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sys@ORCL>col table_owner for a10
sys@ORCL>col table_name for a15
sys@ORCL>col partition_name for a20
sys@ORCL>col high_value for a100
sys@ORCL>set linesize 300
sys@ORCL>select table_owner,table_name,partition_name,high_value from dba_tab_partitions where table_name='INTERVAL_SALES';

TABLE_OWNE TABLE_NAME      PARTITION_NAME       HIGH_VALUE
---------- --------------- -------------------- ----------------------------------------------------------------------------------------------------
SYS        INTERVAL_SALES  P0                   TO_DATE(' 2008-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  P1                   TO_DATE(' 2009-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  P2                   TO_DATE(' 2009-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  P3                   TO_DATE(' 2010-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  SYS_P41              TO_DATE(' 2010-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')



可以看到INTERVAL_sales表多了一个SYS_P41分区,分区的HIGH_VALUE为2010-02-01,分区是增加了一个月
再插入间隔再大一些的测试数据看看变化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
sys@ORCL>insert into interval_sales values(2,101,to_date('2010-08-03','yyyy-mm-dd'),'a',201,101,10);

1 row created.

sys@ORCL>commit;

Commit complete.

sys@ORCL>select * from interval_sales;

   PROD_ID    CUST_ID TIME_ID             CHA   PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- ------------------- --- ---------- ------------- -----------
         1        101 2008-06-01 00:00:00 a          201           101          10
         2        101 2010-01-03 00:00:00 a          201           101          10
         2        101 2010-08-03 00:00:00 a          201           101          10

sys@ORCL>select table_owner,table_name,partition_name,high_value from dba_tab_partitions where table_name='INTERVAL_SALES';

TABLE_OWNE TABLE_NAME      PARTITION_NAME       HIGH_VALUE
---------- --------------- -------------------- ----------------------------------------------------------------------------------------------------
SYS        INTERVAL_SALES  P0                   TO_DATE(' 2008-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  P1                   TO_DATE(' 2009-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  P2                   TO_DATE(' 2009-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  P3                   TO_DATE(' 2010-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  SYS_P41              TO_DATE(' 2010-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  SYS_P42              TO_DATE(' 2010-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

6 rows selected.

sys@ORCL>insert into interval_sales values(2,101,to_date('2010-05-03','yyyy-mm-dd'),'a',201,101,10);

1 row created.

sys@ORCL>commit;

Commit complete.

sys@ORCL>select * from interval_sales;

   PROD_ID    CUST_ID TIME_ID             CHA   PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- ------------------- --- ---------- ------------- -----------
         1        101 2008-06-01 00:00:00 a          201           101          10
         2        101 2010-01-03 00:00:00 a          201           101          10
         2        101 2010-05-03 00:00:00 a          201           101          10
         2        101 2010-08-03 00:00:00 a          201           101          10

sys@ORCL>select table_owner,table_name,partition_name,high_value from dba_tab_partitions where table_name='INTERVAL_SALES';

TABLE_OWNE TABLE_NAME      PARTITION_NAME       HIGH_VALUE
---------- --------------- -------------------- ----------------------------------------------------------------------------------------------------
SYS        INTERVAL_SALES  P0                   TO_DATE(' 2008-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  P1                   TO_DATE(' 2009-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  P2                   TO_DATE(' 2009-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  P3                   TO_DATE(' 2010-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  SYS_P41              TO_DATE(' 2010-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  SYS_P42              TO_DATE(' 2010-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
SYS        INTERVAL_SALES  SYS_P43              TO_DATE(' 2010-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

7 rows selected.



可以看出插入2010-08-03的数据会创建一个2010-09-01的分区,然后再插入2010-05-03的数据会创建2010-06-01的分区,说明所有自动创建的分区都会按整个月来控制。控制这个时间间隔的就是NUMTOYMINTERVAL(1, 'MONTH')。
NUMTOYMINTERVAL(1, 'YEAR') 一年
NUMTOYMINTERVAL(1, 'MONTH') 一个月
NUMTODSINTERVAL(1, 'DAY') 一天
NUMTODSINTERVAL(1, 'HOUR') 一小时
NUMTODSINTERVAL(1, 'MINUTE') 一分钟
NUMTODSINTERVAL(1, 'SECOND') 一秒

使用数值做分区键也可以使用Interval Partition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
sys@ORCL>create table interval_num
  2  (id      number,
  3   name    varchar2(20),
  4   time_id date
  5  )
  6  partition by range (id)
  7  interval(20)
  8  (partition p0 values less than (20));

Table created.

sys@ORCL>insert into interval_num values(1,'a',to_date('2016-01-01','yyyy-mm-dd'));

1 row created.

sys@ORCL>insert into interval_num values(21,'a',to_date('2016-01-01','yyyy-mm-dd'));

1 row created.

sys@ORCL>commit;

Commit complete.

sys@ORCL>select table_owner,table_name,partition_name,high_value from dba_tab_partitions where table_name='INTERVAL_NUM';

TABLE_OWNE TABLE_NAME      PARTITION_NAME       HIGH_VALUE
---------- --------------- -------------------- ----------------------------------------------------------------------------------------------------
SYS        INTERVAL_NUM    P0                   20
SYS        INTERVAL_NUM    SYS_P44              40



使用Interval Partition的注意事项,自动创建的分区名都是自动分配的,类似SYS_P**的,如果觉得这种名字不合规的话可以进行修改
1
2
3
4
5
6
7
8
9
10
sys@ORCL>alter table interval_num rename partition sys_p44 to p1;

Table altered.

sys@ORCL>select table_owner,table_name,partition_name,high_value from dba_tab_partitions where table_name='INTERVAL_NUM';

TABLE_OWNE TABLE_NAME      PARTITION_NAME       HIGH_VALUE
---------- --------------- -------------------- ----------------------------------------------------------------------------------------------------
SYS        INTERVAL_NUM    P0                   20
SYS        INTERVAL_NUM    P1                   40



非Interval Partition转为Partition,使用alter table table_name set interval(...);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
sys@ORCL> create table interval_num
        2        (id      number,
        3      name    varchar2(20),
        4      time_id date
        5     )
        6     partition by range (id)
        7     (partition p0 values less than (20));

Table created.

sys@ORCL>insert into interval_num(id) values(1);

1 row created.

sys@ORCL>insert into interval_num(id) values(21);
insert into interval_num(id) values(21)
            *
ERROR at line 1:
ORA-14400: inserted partition key does not map to any partition


sys@ORCL>alter table interval_num set interval(20);

Table altered.

sys@ORCL>insert into interval_num(id) values(21);

1 row created.

sys@ORCL>select table_owner,table_name,partition_name,high_value from dba_tab_partitions where table_name='INTERVAL_NUM';

TABLE_OWNER TABLE_NAME  PARTITION_ HIGH_VALUE
--------------- --------------- ---------- --------------------------------------------------------------------------------
SYS     INTERVAL_NUM    P0     20
SYS     INTERVAL_NUM    SYS_P45    40



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-307969-1-1.html 上篇帖子: 安装unxiodbc软件,连接oracle数据库 下篇帖子: 求助,rac监听问题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表