千家信息网

Oracle11g新特性:引用分区(reference partitioning)

发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,引用分区(reference partitioning)是Oracle Database 11g Release 1及以上版本的一个新特性。它处理的是父/子对等分区的问题。也就是说,要以某种方式对子表
千家信息网最后更新 2025年01月20日Oracle11g新特性:引用分区(reference partitioning)

引用分区(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表:

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表:

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分区而不会违反引用完整性约束。尽管我们都很清楚这一点,但数据库并不知道:

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,只需要截除这个表:

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.

创建一个新的子表:

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表的结构,并发现它有两个分区。因此,子表会有两个分区。实际上,如果现在查询数据字典可以得到:

zx@ORCL>set linesize 200zx@ORCL>col table for a20zx@ORCL>col partition_name for a20zx@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_2016ORDERS                                                                                     PART_2017ORDER_LINE_ITEMS                                                                           PART_2016ORDER_LINE_ITEMS                                                                           PART_2017

可以看到两个表的结构完全相同。另外,由于数据库知道这两个表是相关联的,可以删除父表分区,并让它自动清除相关的子表分区(因为子表从父表继承而来,所以父表分区结构的任何调整都会向下级联传递到子表分区):

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_2017ORDER_LINE_ITEMS                                                                           PART_2017

因此,之前不允许完成的DROP现在则是完全允许的,它会自动级联传递到子表。另外如果使用ADD增加一个分区:

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_2017ORDERS                                                                                     PART_2018ORDER_LINE_ITEMS                                                                           PART_2017ORDER_LINE_ITEMS                                                                           PART_2018

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


参考《ORACLE DATABASE 9I10G11G编程艺术》

官方文档:http://docs.oracle.com/cd/E11882_01/server.112/e25523/partition.htm#CACIHDII


数据 数据库 两个 信息 问题 结构 在线 重要 一对一 下级 个子 之间 也就是 也就是说 例子 冗余 完整性 指向 机制 语句 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 国产 网络安全 股票 广州紫琼互联网科技有限公司 大学生网络安全教育视频 兴文县网络安全监察大队电话 汽车企业 技术 软件开发 管家婆软件连接到服务器异常 e游小镇软件开发 怎么给服务器增加盘 软件开发过程有哪些职位 好用的云服务器 大数据报表代码软件开发工程师 大华平台服务器后台配置 信息网络安全 讲话稿 服务器质量保障报告 武汉大学网络安全学院转专业政策 松江区企业数据库销售价格表格 两个软件数据库 软件开发收入算劳务收入吗 说手机违反网络安全 战地1私人服务器有奖励吗 福州微拓网络技术公司招聘 软件开发属于基础研究吗 软件开发 创业失败 开展网络安全监察执法工作 搭建好的代码怎么连接服务器 吴忠网络技术推荐厂家 黄冈虚拟仪器软件开发 暗黑破坏神2网络服务器 软件开发客户需求文档怎么写 数据库 怎么追加
0