从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'?