当前位置:Gxlcms > mysql > 详述Oracle11g中的ReferencePartition

详述Oracle11g中的ReferencePartition

时间:2021-07-01 10:21:17 帮助过:34人阅读

本篇主要介绍11g新推出的Reference Partitioin。Reference Partition针对的业务场景是主外键关联。主表分区之后,借助Reference

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 Production

PL/SQL Release 11.2.0.4.0 - Production

CORE 11.2.0.4.0 Production

TNS for Linux: Version 11.2.0.4.0 - Production

NLSRTL Version 11.2.0.4.0 – Production

2、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 14652

14652, 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' 1

P1 'SYS' 2

P3 default 3

SQL> 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 1

P1 2

P3 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 PARTITION

T_MASTER P1 TABLE PARTITION

T_MASTER P0 TABLE PARTITION

T_DETAIL P3 TABLE PARTITION

T_DETAIL P1 TABLE PARTITION

T_DETAIL P0 TABLE PARTITION

6 rows selected

3、数据插入实验

下面进行数据插入和分区分布实验。首先进行主表数据插入:

SQL> insert into t_master select object_id, owner, object_name, object_type from dba_objects;

120361 rows inserted

SQL> commit;

Commit complete

SQL> 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 inserted

SQL> commit;

Commit complete

SQL> 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' 33996

T_MASTER P1 'SYS' 37817

T_MASTER P3 default 48548

SQL> 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 33996

T_DETAIL P1 37817

T_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 inserted

SQL> commit;

Commit complete

SQL> 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_DETAIL');

TABLE_NAME PARTITION_NAME HIGH_VALUE NUM_ROWS

------------------------------ -------------------- --------------- ----------

T_DETAIL P0 67992

T_DETAIL P1 75634

T_DETAIL P3 97096

那么,Reference Partition在实际运维场景下的意义在于何处呢?

人气教程排行