oracle只支持两种组合分区表:range-list和range-hash组合分区表。我们测试一下创建方法,以及组合分区表中的 表、分区、子分区 的表空间如何存储:
--1.创建range-hash组合分区表testrhp1
SQL> create table testrhp1( a number(5), b varchar2(10) )
2 partition by range(a)
3 subpartition by hash(b) subpartitions 2(
4 partition testrhp1 values less than(10)(
5 subpartition tetsrhp1_sub1 tablespace tp_p1,
6 subpartition testrhp1_sub2 tablespace tp_p2
7 ),
8 partition testrhp2 values less than(20)(
9 subpartition testrhp2_sub1 tablespace tp_p1,
10 subpartition testrhp2_sub2 tablespace tp_p2
11 )
12 );
表已创建。
--2.创建时可以不指定子分区的个数
SQL> create table testrhp2( a number(5), b varchar2(10) )
2 partition by range(a)
3 subpartition by hash(b) (
4 partition testrhp1 values less than(10)(
5 subpartition tetsrhp1_sub1 tablespace tp_p1,
6 subpartition testrhp1_sub2 tablespace tp_p2
7 ),
8 partition testrhp2 values less than(20)(
9 subpartition testrhp2_sub1 tablespace tp_p1,
10 subpartition testrhp2_sub2 tablespace tp_p2
11 )
12 );
表已创建。
--3.既然可以不指定子分区的数目,那也可以创建不同数据的子分区
--(哈希分区应该建立2的幂个分区,这里只是测试,所以建立了3个)
SQL> create table testrhp3( a number(5), b varchar2(10) )
2 partition by range(a)
3 subpartition by hash(b) (
4 partition testrhp1 values less than(10)(
5 subpartition tetsrhp1_sub1 tablespace tp_p1,
6 subpartition testrhp1_sub2 tablespace tp_p2
7 ),
8 partition testrhp2 values less than(20)(
9 subpartition testrhp2_sub1 tablespace tp_p1,
10 subpartition testrhp2_sub2 tablespace tp_p2,
11 subpartition testrhp2_sub3 tablespace tp_p3
12 )
13 );
表已创建。
--4.我们查询一下分区和子分区的信息
SQL> select TABLE_NAME, PARTITION_NAME, TABLESPACE_NAME, HIGH_VALUE
2 from user_tab_partitions where table_name like 'TESTRHP%';
TABLE_NAME PARTITION_NAME TABLESPACE_NAME HIGH_VALUE
------------ ---------------- ---------------- -----------
TESTRHP1 TESTRHP1 TP_TEST 10
TESTRHP1 TESTRHP2 TP_TEST 20
TESTRHP2 TESTRHP1 TP_TEST 10
TESTRHP2 TESTRHP2 TP_TEST 20
TESTRHP3 TESTRHP1 TP_TEST 10
TESTRHP3 TESTRHP2 TP_TEST 20
已选择6行。
SQL> select TABLE_NAME, PARTITION_NAME, SUBPARTITION_NAME, TABLESPACE_NAME
2 from user_tab_subpartitions where table_name like 'TESTRHP%';
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME
----------- --------------- ------------------- ---------------
TESTRHP1 TESTRHP1 TETSRHP1_SUB1 TP_P1
TESTRHP1 TESTRHP1 TESTRHP1_SUB2 TP_P2
TESTRHP1 TESTRHP2 TESTRHP2_SUB1 TP_P1
TESTRHP1 TESTRHP2 TESTRHP2_SUB2 TP_P2
TESTRHP2 TESTRHP1 TETSRHP1_SUB1 TP_P1
TESTRHP2 TESTRHP1 TESTRHP1_SUB2 TP_P2
TESTRHP2 TESTRHP2 TESTRHP2_SUB1 TP_P1
TESTRHP2 TESTRHP2 TESTRHP2_SUB2 TP_P2
TESTRHP3 TESTRHP1 TETSRHP1_SUB1 TP_P1
TESTRHP3 TESTRHP1 TESTRHP1_SUB2 TP_P2
TESTRHP3 TESTRHP2 TESTRHP2_SUB1 TP_P1
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME
----------- --------------- ------------------- ---------------
TESTRHP3 TESTRHP2 TESTRHP2_SUB2 TP_P2
TESTRHP3 TESTRHP2 TESTRHP2_SUB3 TP_P3
已选择13行。
--5.range-list组合分区的创建方法与此类似
SQL> create table testrlp( a number(5), b varchar2(10) )
2 partition by range(a)
3 subpartition by list(b)
4 (
5 partition testrlp1 values less than(10)
6 (
7 subpartition testlp1_sub1 values('1','3','5'),
8 subpartition testlp1_sub2 values('2','4','6')
9 ),
10 partition testlp2 values less than(20)
11 (
12 subpartition testlp2_sub1 values('1','3','5'),
13 subpartition testlp2_sub2 values('2','4','6')
14 )
15 );
表已创建。
--6.下面我们测试一下,组合分区表中的 表、分区、子分区 的表空间如何存储
组合分区表中,表和分区并没有分配段空间,只有子分区才分配段空间。所以我们创建组合分区表时要考虑的就是子分区的存储。那么,子分区的存储与什么相关呢?
(1)子分区若指定表空间,则以子分区所指定表空间为准;
(2)子分区若未指定表空间,则以其所在分区表空间为准;
(3)若其所在分区也未指定表空间,则以该分区所在表指定的表空间为准;
(4)若表也未指定表空间,则以该表所在用户默认表空间为准。
--6.1验证(4):都不指定表空间,则以该表所在用户的默认表空间为准
--当前用户
SQL> show user
USER 为"TEST"
--当前用户的默认表空间
SQL> select username, default_tablespace from user_users;
USERNAME DEFAULT_TABLESPACE
------------------------------ ------------------------------
TEST TP_TEST
--创建一个没有指定任何表空间的range-list组合分区表
SQL> create table testrlp(a number(2), b varchar2(10))
2 partition by range(a)
3 subpartition by list(b)
4 (
5 partition testrlp1 values less than(10)
6 (
7 subpartition testrlp1_sub1 values('1','3','5'),
8 subpartition testrlp1_sub2 values('2','4','6')
9 ),
10 partition testrlp2 values less than(20)
11 (
12 subpartition testrlp2_sub1 values('1','3','5'),
13 subpartition testrlp2_sub2 values('2','4','6')
14 )
15 );
表已创建。
--查询表TESTRLP的表空间:无
SQL> select TABLE_NAME, TABLESPACE_NAME from user_tables where table_name ='TESTRLP';
TABLE_NAME TABLESPACE_NAME
------------------------------ ------------------------------
TESTRLP
--查询表TESTRLP的两个分区的表空间:TP_TEST。似乎是分配了表空间
SQL> select TABLE_NAME, PARTITION_NAME, TABLESPACE_NAME
2 from user_tab_partitions
3 where table_name = 'TESTRLP';
TABLE_NAME PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ---------------
TESTRLP TESTRLP1 TP_TEST
TESTRLP TESTRLP2 TP_TEST
--查询表TESTRLP的四个子分区的表空间:TP_TEST。
SQL> select TABLE_NAME, PARTITION_NAME, SUBPARTITION_NAME, TABLESPACE_NAME
2 from user_tab_subpartitions
3 where table_name = 'TESTRLP';
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------ ---------------
TESTRLP TESTRLP1 TESTRLP1_SUB1 TP_TEST
TESTRLP TESTRLP1 TESTRLP1_SUB2 TP_TEST
TESTRLP TESTRLP2 TESTRLP2_SUB1 TP_TEST
TESTRLP TESTRLP2 TESTRLP2_SUB2 TP_TEST
--我们看一下表TESTRLP分配的段:确实只有子分区的段空间,分区并没有分配段空间。
SQL> select SEGMENT_NAME, PARTITION_NAME, SEGMENT_TYPE, TABLESPACE_NAME
2 from user_segments
3 where segment_name = 'TESTRLP';
SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE TABLESPACE_NAME
-------------- ------------------------ ------------------ --------
TESTRLP TESTRLP1_SUB2 TABLE SUBPARTITION TP_TEST
TESTRLP TESTRLP2_SUB1 TABLE SUBPARTITION TP_TEST
TESTRLP TESTRLP2_SUB2 TABLE SUBPARTITION TP_TEST
TESTRLP TESTRLP1_SUB1 TABLE SUBPARTITION TP_TEST
--其实这和表与分区的关系是一样的(参考《分区表与分区索引(一):范围分区表的操作》)。
--6.2验证(3):若其所在分区也未指定表空间,则以该分区所在表指定的表空间为准
SQL> drop table testrlp;
表已丢弃。
SQL> create table testrlp(a number(2), b varchar2(10))
2 partition by range(a)
3 subpartition by list(b)
4 (
5 partition testrlp1 values less than(10)
6 (
7 subpartition testrlp1_sub1 values('1','3','5'),
8 subpartition testrlp1_sub2 values('2','4','6')
9 ),
10 partition testrlp2 values less than(20)
11 (
12 subpartition testrlp2_sub1 values('1','3','5'),
13 subpartition testrlp2_sub2 values('2','4','6')
14 )
15 )
16 tablespace tp_p1;
表已创建。
SQL> select TABLE_NAME, PARTITION_NAME, SUBPARTITION_NAME, TABLESPACE_NAME
2 from user_tab_subpartitions
3 where table_name = 'TESTRLP';
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME
----------- --------------- ------------------ -----------------
TESTRLP TESTRLP1 TESTRLP1_SUB1 TP_P1
TESTRLP TESTRLP1 TESTRLP1_SUB2 TP_P1
TESTRLP TESTRLP2 TESTRLP2_SUB1 TP_P1
TESTRLP TESTRLP2 TESTRLP2_SUB2 TP_P1
SQL>
--6.3验证(2):子分区若未指定表空间,则以其所在分区表空间为准;
SQL> drop table testrlp;
表已丢弃。
SQL> create table testrlp(a number(2), b varchar2(10)) tablespace tp_p1
2 partition by range(a)
3 subpartition by list(b)
4 (
5 partition testrlp1 values less than(10) tablespace tp_p2
6 (
7 subpartition testrlp1_sub1 values('1','3','5'),
8 subpartition testrlp1_sub2 values('2','4','6')
9 ),
10 partition testrlp2 values less than(20)
11 (
12 subpartition testrlp2_sub1 values('1','3','5'),
13 subpartition testrlp2_sub2 values('2','4','6')
14 )
15 );
表已创建。
--分区tetrlp1指定了表空间tp_p2,所以其子分区testrp1_sub1和testrp1_sub2都分配在tp_p2中;
--而分区testrp2未指定表空间,所以其子分区testrp2_sub1和testrp2_sub2分配在表testrlp指定的表空间tp_p1中
SQL> select TABLE_NAME, PARTITION_NAME, SUBPARTITION_NAME, TABLESPACE_NAME
2 from user_tab_subpartitions
3 where table_name = 'TESTRLP';
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------ ---------------
TESTRLP TESTRLP1 TESTRLP1_SUB1 TP_P2
TESTRLP TESTRLP1 TESTRLP1_SUB2 TP_P2
TESTRLP TESTRLP2 TESTRLP2_SUB1 TP_P1
TESTRLP TESTRLP2 TESTRLP2_SUB2 TP_P1
--6.4验证(1):子分区若指定表空间,则以子分区所指定表空间为准;
SQL> drop table testrlp;
表已丢弃。
SQL> create table testrlp(a number(2), b varchar2(10)) tablespace tp_p1
2 partition by range(a)
3 subpartition by list(b)
4 (
5 partition testrlp1 values less than(10) tablespace tp_p2
6 (
7 subpartition testrlp1_sub1 values('1','3','5') tablespace tp_p3,
8 subpartition testrlp1_sub2 values('2','4','6')
9 ),
10 partition testrlp2 values less than(20)
11 (
12 subpartition testrlp2_sub1 values('1','3','5'),
13 subpartition testrlp2_sub2 values('2','4','6')
14 )
15 );
表已创建。
--子分区testrp1_sub1指定了表空间tp_p3,所以该子分区分配在tp_p3中;
--子分区testrp1_sub2未指定表空间,所以其表空间分配在所在分区tetrlp1指定的表空间tp_p2中;
--而分区testrp2未指定表空间,所以其子分区testrp2_sub1和testrp2_sub2分配在表testrlp指定的表空间tp_p1中
SQL> select TABLE_NAME, PARTITION_NAME, SUBPARTITION_NAME, TABLESPACE_NAME
2 from user_tab_subpartitions
3 where table_name = 'TESTRLP';
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------ ---------------
TESTRLP TESTRLP1 TESTRLP1_SUB1 TP_P3
TESTRLP TESTRLP1 TESTRLP1_SUB2 TP_P2
TESTRLP TESTRLP2 TESTRLP2_SUB1 TP_P1
TESTRLP TESTRLP2 TESTRLP2_SUB2 TP_P1
SQL>
我们看2中的写法:
--2.创建时可以不指定子分区的个数
create table testrhp2( a number(5), b varchar2(10) )
partition by range(a)
subpartition by hash(b) (
partition testrhp1 values less than(10)(
subpartition tetsrhp1_sub1 tablespace tp_p1,
subpartition testrhp1_sub2 tablespace tp_p2
),
partition testrhp2 values less than(20)(
subpartition testrhp2_sub1 tablespace tp_p1,
subpartition testrhp2_sub2 tablespace tp_p2
)
);
看起来似乎有些麻烦,因为我每个分区创建的子分区个数和存储表空间都是一样的,但每个分区都需要写一次。
对此,oracle提供了另外的一种写法:子分区模板。
SQL> create table testrhp2( a number(5), b varchar2(10) )
2 partition by range(a)
3 subpartition by hash(b)
4 subpartition template(
5 subpartition sub1 tablespace tp_p1,
6 subpartition sub2 tablespace tp_p2
7 )
8 (
9 partition testrhp1 values less than(10),
10 partition testrhp2 values less than(20)
11 );
表已创建。
SQL> select TABLE_NAME, PARTITION_NAME, SUBPARTITION_NAME, TABLESPACE_NAME
2 from user_tab_subpartitions where table_name = 'TESTRHP2';
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME TABLESPACE_NAME
----------- --------------- ----------------- -------------------
TESTRHP2 TESTRHP1 TESTRHP1_SUB1 TP_P1
TESTRHP2 TESTRHP1 TESTRHP1_SUB2 TP_P2
TESTRHP2 TESTRHP2 TESTRHP2_SUB1 TP_P1
TESTRHP2 TESTRHP2 TESTRHP2_SUB2 TP_P2
SQL>