下面是设计分区方案过程中的一个典型问题,并非所有表都需要根据其进行分区的列。假设要创建一个销
售系统,该系统包括两个简单的表(sales和customers)。
customers表的创建如下所示:
create table customers
(
cust_id number primary key,
cust_name varchar2(200),
rating varchar2(1) not null
)
partition by list (rating)
(
partition pA values ('A'),
partition pB values ('B')
);
sales表的创建如下所示。它是customers表的一个子表。
create table sales
(
sales_id number primary key,
cust_id number not null,
sales_amt number,
constraint fk_sales_01
foreign key (cust_id)
references customers
);
在理想情况下,希望用相同的方式对sales表和customers表进行分区,根据rating列进行列表分区。
但有一个严重的问题,sales表没有名为rating的列,那么如何根据一个不存在的列进行分区呢?
在Oracle 11g中,可以使用一个称为引用分区的新特性。下面的示例显示了如何将该特性应用于sales
表:
create table sales
(
sales_id number primary key,
cust_id number not null,
sales_amt number,
constraint fk_sales_01
foreign key (cust_id)
references customers
)
partition by reference (fk_sales_01);
这段代码创建了与父表customers中相同的分区。注意,虽然没有名为rating的列,但仍根据该列对表
进行了分区。partition by reference (fk_sales_01)子句包括了分区定义中的外键名。该语句指
示Oracle 11g确认通过父表(在该示例中为customers)中使用的方案进行了分区。注意cust_id列
的NOT NULL约束,这是引用分区所必需的。
检查sales表中分区的分区边界:
SQL> select partition_name, high_value
from user_tab_partitions
where table_name = 'SALES';
PARTITION_NAME HIGH_VALUE
--------------- -------------------------------
PA
PB
HIGH_VALUE为空,这意味着此处的边界派生自父表。分区的名称与父表中的名称相同。可以通过查询
user_part_tables视图来检查分区的类型。一个名为ref_ptn_constraint_name的特殊列显示了外
键约束名称。
SQL> select table_name, partitioning_type, ref_ptn_constraint_name
from user_part_tables
where table_name in ('CUSTOMERS','SALES');
TABLE_NAME PARTITION REF_PTN_CONSTRAINT_NAME
------------------------------ --------- --------------------------
CUSTOMERS LIST
SALES
如果希望按照父表分区的方式对子表进行分区,但没有相同的列,又不仅为了分区而引入这些列,此时引
用分区将非常方便。而且,不必针对每个子表显式声明一个很长的分区子句。