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

[经验分享] Oracle11g新特性:引用分区(reference partitioning)

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-1-24 09:31:03 | 显示全部楼层 |阅读模式
引用分区(reference partitioning)是Oracle Database 11g Release 1及以上版本的一个新特性。它处理的是父/子对等分区的问题。也就是说,要以某种方式对子表分区,使得各个子表分区分别与一个你表分区存在一对一的关系。在某些情况下这很重要,例如假设有一个数据仓库,你希望保证一定数量的数据在线(例如最近5年的ORDER信息),而且要确保相关联的子表数据(ORDER_LINE_ITEMS数据)也在线。在这个经典的例子中,ORDERS表通常有一个ORDER_DATE列,所以可以很容易地按月分区,这也有利于保证最近5年的数据在线。随着时间推移,只需加载下一个朋的分区,并删除最老的分区。不过,考虑ORDER_LINE_ITEMS表时会看到存在一个问题。它没有ORDER_DATE列,而且ORDER_LINE_ITEMS表中根本没法有可以据以分区的列,因此无法帮助清除老信息或加载新信息。
过去,在引用分区出现之前,开发人员必须对数据逆规范化(denormalize),具体做法是:从父表ORDERS将ORDER_DATE属性复制到子表ORDER_LINE_ITEMS。这会引入冗余数据,相应地带来数据冗余存在的一系列常见问题,比如存储开销增加、数据加载资源增加、级联更新问题(如果修改父表,还必须确保更新父表数据的所有副本),等等。另外,如果在数据库中启用了外键约束(而且确实应当启用外键约束),会发现无法截除或删除父表中原来的分区。例如,下面来创建传统的ORDERS和ORDER_LINE_ITEMS表。先看ORDERS表:
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
zx@ORCL>create table orders
  2  (
  3    order#      number primary key,
  4    order_date  date NOT NULL,
  5    data       varchar2(30)
  6  )
  7  enable row movement
  8  PARTITION BY RANGE (order_date)
  9  (
10    PARTITION part_2016 VALUES LESS THAN (to_date('01-01-2017','dd-mm-yyyy')) ,
11    PARTITION part_2017 VALUES LESS THAN (to_date('01-01-2018','dd-mm-yyyy'))
12  )
13  /

Table created.

zx@ORCL>insert into orders values
  2  ( 1, to_date( '01-jun-2016', 'dd-mon-yyyy' ), 'xxx' );

1 row created.

zx@ORCL>insert into orders values
  2  ( 2, to_date( '01-jun-2017', 'dd-mon-yyyy' ), 'xxx' );

1 row created.

zx@ORCL>commit;

Commit complete.



现在来创建ORDER_LINE_ITEMS表,并插入一些数据指向ORDERS表:
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
zx@ORCL>create table order_line_items
  2  (
  3    order#      number,
  4    line#       number,
  5    order_date  date, -- manually copied from ORDERS!
  6    data       varchar2(30),
  7    constraint c1_pk primary key(order#,line#),
  8    constraint c1_fk_p foreign key(order#) references orders
  9  )
10  enable row movement
11  PARTITION BY RANGE (order_date)
12  (
13    PARTITION part_2016 VALUES LESS THAN (to_date('01-01-2017','dd-mm-yyyy')) ,
14    PARTITION part_2017 VALUES LESS THAN (to_date('01-01-2018','dd-mm-yyyy'))
15  )
16  /

Table created.

zx@ORCL>insert into order_line_items values
  2  ( 1, 1, to_date( '01-jun-2016', 'dd-mon-yyyy' ), 'yyy' );

1 row created.

zx@ORCL>insert into order_line_items values
  2  ( 2, 1, to_date( '01-jun-2017', 'dd-mon-yyyy' ), 'yyy' );

1 row created.

zx@ORCL>commit;

Commit complete.



现在如果要删除包含2016年数据的ORDER_LINE_ITEMS分区,也可以删除对应2016年的ORDERS分区而不会违反引用完整性约束。尽管我们都很清楚这一点,但数据库并不知道:
1
2
3
4
5
6
7
8
9
zx@ORCL>alter table order_line_items drop partition part_2016;

Table altered.

zx@ORCL>alter table orders           drop partition part_2016;
alter table orders           drop partition part_2016
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys



所以,对数据逆规范化的做活很笨拙,会耗费资源,而且可能破坏数据的完整性。不仅如此,它还会妨碍管理分区表时经常需要做的一项工作:清除老信息。

下面来看引用分区。采用引用分区,子表会继承父表的分区机制,而不必对分区键逆规范化,而且更重要的是,它会让数据库了解这个子表与父表之间存在对等分区特点。也就是说,截除或删除生意人子表分区时,也能删除或截除父表分区。
要重新实现前面的例子,语法很简单,如下所示,这里将重用现胡的你表ORDERS,只需要截除这个表:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
zx@ORCL>drop table order_line_items cascade constraints;

Table dropped.

zx@ORCL>truncate table orders;

Table truncated.

zx@ORCL>insert into orders values
  2  ( 1, to_date( '01-jun-2016', 'dd-mon-yyyy' ), 'xxx' );

1 row created.

zx@ORCL>insert into orders values
  2  ( 2, to_date( '01-jun-2017', 'dd-mon-yyyy' ), 'xxx' );

1 row created.

zx@ORCL>commit;

Commit complete.



创建一个新的子表:
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
zx@ORCL>create table order_line_items
  2  (
  3    order#      number NOT NULL,
  4    line#       number NOT NULL,
  5    data       varchar2(30),
  6    constraint c1_pk primary key(order#,line#),
  7    constraint c1_fk_p foreign key(order#) references orders
  8  )
  9  enable row movement
10  partition by reference(c1_fk_p)
11  /

Table created.

zx@ORCL>insert into order_line_items values
  2  ( 1, 1, 'yyy' );

1 row created.

zx@ORCL>insert into order_line_items values
  2  ( 2, 1, 'yyy' );

1 row created.

zx@ORCL>commit;

Commit complete.



神奇之处就在CREATE TABLE语句的第10行。在这里,我们将区间分区语句替换为PARTITION BY REFERENCE。
这允许我们指定要使用的外键约束,从而发现分区机制。在这里可以看到外键指向ORDERS表——数据库读取ORDERS表的结构,并发现它有两个分区。因此,子表会有两个分区。实际上,如果现在查询数据字典可以得到:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
zx@ORCL>set linesize 200
zx@ORCL>col table for a20
zx@ORCL>col partition_name for a20
zx@ORCL>select table_name, partition_name
  2    from user_tab_partitions
  3   where table_name in ( 'ORDERS', 'ORDER_LINE_ITEMS' )
  4   order by table_name, partition_name
  5  /

TABLE_NAME                                                                                 PARTITION_NAME
------------------------------------------------------------------------------------------ --------------------
ORDERS                                                                                     PART_2016
ORDERS                                                                                     PART_2017
ORDER_LINE_ITEMS                                                                           PART_2016
ORDER_LINE_ITEMS                                                                           PART_2017



可以看到两个表的结构完全相同。另外,由于数据库知道这两个表是相关联的,可以删除父表分区,并让它自动清除相关的子表分区(因为子表从父表继承而来,所以父表分区结构的任何调整都会向下级联传递到子表分区):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
zx@ORCL>alter table orders drop partition part_2016 update global indexes;

Table altered.

zx@ORCL>select table_name, partition_name
  2    from user_tab_partitions
  3   where table_name in ( 'ORDERS', 'ORDER_LINE_ITEMS' )
  4   order by table_name, partition_name
  5  /

TABLE_NAME                                                                                 PARTITION_NAME
------------------------------------------------------------------------------------------ --------------------
ORDERS                                                                                     PART_2017
ORDER_LINE_ITEMS                                                                           PART_2017



因此,之前不允许完成的DROP现在则是完全允许的,它会自动级联传递到子表。另外如果使用ADD增加一个分区:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
zx@ORCL>alter table orders add partition
  2  part_2018 values less than
  3  (to_date( '01-01-2019', 'dd-mm-yyyy' ));

Table altered.

zx@ORCL>select table_name, partition_name
  2    from user_tab_partitions
  3   where table_name in ( 'ORDERS', 'ORDER_LINE_ITEMS' )
  4   order by table_name, partition_name
  5  /

TABLE_NAME                                                                                 PARTITION_NAME
------------------------------------------------------------------------------------------ --------------------
ORDERS                                                                                     PART_2017
ORDERS                                                                                     PART_2018
ORDER_LINE_ITEMS                                                                           PART_2017
ORDER_LINE_ITEMS                                                                           PART_2018



可以看到,这个操作也会向下级联传递。父表与子表之间存在一种一对一的关系。



运维网声明 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-332746-1-1.html 上篇帖子: check_oracle_health监控oracle 下篇帖子: ORACLE 10GR2 DATAGUARD ON RHEL 6
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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