首页 / 数据库 / MySQL / 详述Oracle 11g中的Reference Partition
Data Partition是Oracle早期提出的一项针对大数据对象的解决方案。经过若干版本的演变,Partition依然是目前比较流行、应用广泛并且接受程度较高的技术策略。从Oracle产品线角度,Partition的成功是与Oracle不断丰富完善分区技术和方案是分不开的。在每一个版本中,Partition技术都推出一些新的进步和发展。无论是8、8i还是11g、12c,Partition技术都是在不断的向前进步,来满足更加复杂的实际应用需求。本篇主要介绍11g新推出的Reference Partitioin。Reference Partition针对的业务场景是主外键关联。主表分区之后,借助Reference Partition可以实现自动的子表分区(不管子表上有无分区键)。经过Reference Partition分区之后,在同一个主表分区中的数据记录,对应到的子表记录,全部都在相同的子表分区上。这种特性和分区类型,从性能和管理两个方面,都可以给日常运维带来很多好处方便。下面笔者将通过一系列实验来介绍Reference Partiton。1、实验环境介绍笔者选择Oracle 11g进行测试,具体版本为11.2.0.4。SQL> select * from v$version;BANNER-----------------------------------Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit ProductionPL/SQL Release 11.2.0.4.0 - ProductionCORE 11.2.0.4.0 ProductionTNS for Linux: Version 11.2.0.4.0 - ProductionNLSRTL Version 11.2.0.4.0 – Production2、Reference Partition数据表创建和普通主外键数据表创建没有过多差异,首先我们需要创建带分区的主表。SQL> create table t_master 2 ( object_id number, 3 owner varchar2(100), 4 object_name varchar2(100), 5 object_type varchar2(100) 6 ) 7 partition by list(owner) –List分区类型 8 ( 9 partition p0 values ("PUBLIC"), 10 partition p1 values ("SYS"), 11 partition p3 values (default) 12 ) 13 ;--添加主键约束SQL> alter table t_master add constraint pk_t_master primary key (object_id);Table altered创建子表,注意:Reference Partition并不要求子表中包括分区键,引用关系就是子表的分区依据。另外:使用Reference Partition要求创建子表和定义外键约束在同一个语句中。SQL> create table t_detail 2 ( object_id number, 3 master_id number, 4 obj_comment varchar2(100), 5 obj_type varchar2(100), 6 constraint fk_mas_det foreign key (master_id) references t_master(object_id) 7 ) partition by reference(fk_mas_det); create table t_detail( object_id number, master_id number, obj_comment varchar2(100), obj_type varchar2(100), constraint fk_mas_det foreign key (master_id) references t_master(object_id)) partition by reference(fk_mas_det)ORA-14652: 不支持引用分区外键我们收到了一个Oracle报错。首先我们看一下定义reference partition的语法,在create table语句中要创建定义好外键约束的名称。之后,利用partition by语句,将外键作为划分依据进行定义。当前报错ORA-14652,检查一下官方对于这个错误的解释。[oracle@localhost ~]$ oerr ora 1465214652, 00000, "reference partitioning foreign key is not supported"// *Cause: The specified partitioning foreign key was not supported// for reference-partitioned tables. All columns of the// partitioning foreign key must be constrained NOT NULL with// enabled, validated, and not deferrable constraints. Furthermore,// a virtual column cannot be part of the partitioning foreign key.//* Action: Correct the statement to specify a supported// partitioning foreign key.说明中提示了错误原因,如果使用Reference Partition,外键列是不允许为空的。标准外键定义并没有规定外键列必须为空,但是如果使用引用分区技术,就必须要求外键列不能为空。这种约束其实也好理解。Reference Partition不需要明确指定分区键,但是实际上还是需分区键(或者称为分区因素)。如果没有外键值,也就失去了到主表分区的定位功能,Oracle必然不会允许创建。修改建表语句如下:SQL> create table t_detail 2 ( object_id number, 3 master_id number not null, 4 obj_comment varchar2(100), 5 obj_type varchar2(100), 6 constraint fk_mas_det foreign key (master_id) references t_master(object_id) 7 ) partition by reference(fk_mas_det);Table created下面从分区表角度观察两个数据表。SQL> select partition_name, high_value, partition_position from dba_tab_partitions where table_owner="SYS" and table_name="T_MASTER";PARTITION_NAME HIGH_VALUE PARTITION_POSITION-------------------- --------------- ------------------P0 "PUBLIC" 1P1 "SYS" 2P3 default 3SQL> select partition_name, high_value, partition_position from dba_tab_partitions where table_owner="SYS" and table_name="T_DETAIL";PARTITION_NAME HIGH_VALUE PARTITION_POSITION-------------------- --------------- ------------------P0 1P1 2P3 3注意两点:子表t_detail的high_value列为空,说明该数据表并没有一个明确的分区键,主表分区键owner在子表中也不存在。另外,子表分区结构、数量和名称与主表完全相同。从段结构segment上,我们可以看到11g的defered segment creation并没有应用。SQL> select segment_name, partition_name, segment_type from dba_segments where owner="SYS" and segment_name in ("T_MASTER","T_DETAIL");SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE--------------- -------------------- ----------------------T_MASTER P3 TABLE PARTITIONT_MASTER P1 TABLE PARTITIONT_MASTER P0 TABLE PARTITIONT_DETAIL P3 TABLE PARTITIONT_DETAIL P1 TABLE PARTITIONT_DETAIL P0 TABLE PARTITION6 rows selected3、数据插入实验下面进行数据插入和分区分布实验。首先进行主表数据插入:SQL> insert into t_master select object_id, owner, object_name, object_type from dba_objects;120361 rows insertedSQL> commit;Commit completeSQL> exec dbms_stats.gather_table_stats(user,"T_MASTER",cascade => true);PL/SQL procedure successfully completed子表数据插入:SQL> insert into t_detail select seq_t_detail.nextval, object_id, object_name, object_type from dba_objects where object_name not in ("SEQ_T_DETAIL");120361 rows insertedSQL> commit;Commit completeSQL> exec dbms_stats.gather_table_stats(user,"T_DETAIL",cascade => true);PL/SQL procedure successfully completed按照当前的数据关系,应该是一条主表记录,对应一条子表记录的关系。我们检查数据字典情况。SQL> select table_name, partition_name, high_value,num_rows from dba_tab_partitions where table_owner="SYS" and table_name in ("T_MASTER");TABLE_NAME PARTITION_NAME HIGH_VALUE NUM_ROWS------------------------------ -------------------- --------------- ----------T_MASTER P0 "PUBLIC" 33996T_MASTER P1 "SYS" 37817T_MASTER P3 default 48548SQL> select table_name, partition_name, high_value,num_rows from dba_tab_partitions where table_owner="SYS" and table_name in ("T_DETAIL");TABLE_NAME PARTITION_NAME HIGH_VALUE NUM_ROWS------------------------------ -------------------- --------------- ----------T_DETAIL P0 33996T_DETAIL P1 37817T_DETAIL P3 48548数据分布正确。说明:子表分区分布的依据完全在于主表记录对应的分区编号。相同主表分区记录对应的子表记录,一定在相同的子表分区上。不同主表分区记录对应的子表记录,不可能在相同的子表分区上。为便于实验,多插入一些数据:SQL> insert into t_detail select seq_t_detail.nextval, object_id, object_name, object_type from dba_objects where object_name not in ("SEQ_T_DETAIL");120361 rows insertedSQL> commit;Commit completeSQL> exec dbms_stats.gather_table_stats(user,"T_DETAIL",cascade => true);PL/SQL procedure successfully completedSQL> select table_name, partition_name, high_value,num_rows from dba_tab_partitions where table_owner="SYS" and table_name in ("T_DETAIL");TABLE_NAME PARTITION_NAME HIGH_VALUE NUM_ROWS------------------------------ -------------------- --------------- ----------T_DETAIL P0 67992T_DETAIL P1 75634T_DETAIL P3 97096那么,Reference Partition在实际运维场景下的意义在于何处呢?经过笔者之前的讨论,Partition技术的出发点无非在于性能和管理两个角度。性能上最典型的代表是分区裁剪、本地索引;管理最典型代表就是分区摘除、Swip分区归档。最早期Partition是针对性能方面因素比较多,近年来随着硬件性能的提升,管理方面带来的优势,越来越受到重视。下篇中,我们将从性能和管理两个角度,讨论Reference Partition的作用。更多Oracle相关信息见Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12本文永久更新链接地址