创建复合分区表¶
复合分区首先采用范围分区、列表分区或哈希分区进行分区(在CREATE TABLE语句中使用PARTITION BY [RANGE | LIST|HASH]),再使用范围分区、列表分区或哈希分区方式创建二级子分区表(SUBPARITION BY [RANGE|LIST|HASH])。
创建复合分区时,可以指定分区模板。二级子分区表可以参考分区模板创建,也可以根据语法单独指定。如果各个二级子分区表都是参照分区模板创建的,称为“对称复合分区”,否则,称为“非对称复合分区”。
在采用复合分区时,应注意以下规则:
- 当使用分区模板定义二级子分区表时,必须为二级子分区表指定表名。
- 在创建一级子分区表时定义了表空间,在创建二级子分区表的分区模板中也定义了表空间,此时二级子分区表的表空间会继承一级子分区表的表空间。为了使二级子分区表能够继承分区模板中定义的表空间,需要满足下面两个条件中的任意一个即可:
- 如果二级子分区表中含有lob列,且用户已经为某一个二级子分区表的lob列定义了表空间,那么其它二级子分区表中的lob列也必须为它们定义表空间,它们的表空间可以是同一个。
- 如果为列表二级子分区表使用partitioning_storage_clause单独指定LOB存储属性,则不管是在使用分区模板还是定义单独的二级子分区表,你都必需为LOB和数组列指定LOB_segname。
- 在复合分区中,一级子分区表与二级子分区表的分区健可以选择同一列。
- 创建复合分区时,如果没有为一级子分区表指定二级子分区表,并且没有分区模板时,那么将为一级子分区表创建一个默认的二级子分区表,默认二级子分区表定义为:范围分区创建一个MAXVALUE二级子分区表;列表分区创建一个DEFAULT二级子分区表;哈希分区创建一个二级哈希子分区表。
注解
创建复合分区时,如果使用了hash_subparts_by_quantity语法,那么二级分区将根据hash_subparts_by_quantity来创建。
示例1:范围-哈希复合分区表¶
创建复合分区范围-哈希分区表,下面的例子创建四个一级范围分区表,每一个包含四个二级哈希子分区表。因为二级哈希子分区表没有命名,所以系统会自动为其命名,使用STORE IN从句将它们分布到两个表空间(ts1, ts2)中
-- 清理环境
DROP TABLE ts_comp;
DROP TABLESPACE ts1;
DROP TABLESPACE ts2;
-- 创建表空间
CREATE TABLESPACE ts1 DATAFILE 'ts1.dt' SIZE 5M AUTOEXTEND ON NEXT 5M;
CREATE TABLESPACE ts2 DATAFILE 'ts2.dt' SIZE 5M AUTOEXTEND ON NEXT 5M;
-- 创建分区表
CREATE TABLE ts_comp
(
id NUMERIC(6),
time_id DATE
)
PARTITION BY RANGE (time_id)
SUBPARTITION BY HASH (id)
SUBPARTITIONS 4 STORE IN (ts1, ts2)
(
PARTITION p1 VALUES LESS THAN ('2006-APR-01'),
PARTITION p2 VALUES LESS THAN ('2006-JUL-01'),
PARTITION p3 VALUES LESS THAN ('2006-OCT-01'),
PARTITION p4 VALUES LESS THAN ('2007-JAN-01')
);
-- 删除表和表空间
DROP TABLE ts_comp CASCADE;
DROP TABLESPACE ts1;
DROP TABLESPACE ts2;
对于范围-哈希复合分区来说,由于它们的数据都是存储在二级子分区表段,所以它们只是逻辑结构。这些二级子分区表共享相同的逻辑属性。和范围-范围复合分区表中不一样,它们从已有的分区中不能有其他的物理属性,它们也没有要求被放在同一个表空间里。
示例2:含分区模板的范围-哈希复合分区表¶
-- 清理环境
DROP TABLE emp_sub_template;
DROP TABLESPACE ts1;
DROP TABLESPACE ts2;
-- 创建表空间
CREATE TABLESPACE ts1 DATAFILE 'ts1.dt' SIZE 5M AUTOEXTEND ON NEXT 5M;
CREATE TABLESPACE ts2 DATAFILE 'ts2.dt' SIZE 5M AUTOEXTEND ON NEXT 5M;
-- 创建分区表
CREATE TABLE emp_sub_template
(
deptno NUMERIC,
empname VARCHAR(32),
grade NUMERIC
)
PARTITION BY RANGE(deptno)
SUBPARTITION BY HASH(empname)
SUBPARTITION TEMPLATE
(
SUBPARTITION a TABLESPACE ts1,
SUBPARTITION b TABLESPACE ts2
)
(
PARTITION p1 VALUES LESS THAN (1000),
PARTITION p2 VALUES LESS THAN (2000),
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
-- 删除表和表空间
DROP TABLE emp_sub_template CASCADE;
DROP TABLESPACE ts1;
DROP TABLESPACE ts2;
示例3:范围-列表复合分区表¶
在二级列表子分区表的SUBPARTITION子句中,除了表空间物理属性可以被指定,其他的物理属性全部继承主分区表的属性
-- 清理环境
DROP TABLE ts_comp;
-- 创建分区表
CREATE TABLE ts_comp
(
id NUMERIC(6),
time_id DATE,
status VARCHAR(2)
)
PARTITION BY RANGE (time_id)
SUBPARTITION BY LIST (status)
(
PARTITION p1 VALUES LESS THAN ('2006-APR-01')
(
SUBPARTITION p1_a VALUES ('A1', 'A2'),
SUBPARTITION p1_b VALUES ('B1', 'B2', 'B3')
),
PARTITION p2 VALUES LESS THAN ('2006-JUL-01')
(
SUBPARTITION p2_a VALUES ('A1', 'A2'),
SUBPARTITION p2_b VALUES ('B1', 'B2', 'B3')
)
);
一行数据行首先检查它的分区列值定位它属于哪一个一级范围子分区表,然后再检查二级列表子分区的分区键值,看匹配哪一个二级列表子分区表。
下面插入一些数据例子
--映射在p1_a中
INSERT INTO ts_comp VALUES(1,'2006-MAR-01','A1');
--映射在p2_b中
INSERT INTO ts_comp VALUES(2,'2006-MAY-01','B2');
--出现错误,没有合适的分区可以映射
INSERT INTO ts_comp VALUES(3,'2006-OCT-01','A1');
ERROR, 插入元组没有找到合适的子分区表
-- 删除表和表空间
DROP TABLE ts_comp CASCADE;
因为范围-列表复合分区的数据存储在二级子分区表段中,所以它们只是逻辑结构的表。二级列表子分区表和一级列表子分区表一样,可以指定DEFAULT子分区表。
示例4:指定表空间的范围-列表复合分区表¶
下面的例子创建范围-列表复合分区表,并且在一级子分区表及二级子分区表级别指定表空间。每一个一级子分区表的二级子分区表的数量不一样,以及有某些二级子分区表指定为DEFAULT子分区表
-- 清理环境
DROP TABLE ts_comp;
DROP TABLESPACE ts1;
DROP TABLESPACE ts2;
DROP TABLESPACE ts3;
-- 创建表空间
CREATE TABLESPACE ts1 DATAFILE 'ts1.dt' SIZE 5M AUTOEXTEND ON NEXT 5M;
CREATE TABLESPACE ts2 DATAFILE 'ts2.dt' SIZE 5M AUTOEXTEND ON NEXT 5M;
CREATE TABLESPACE ts3 DATAFILE 'ts3.dt' SIZE 5M AUTOEXTEND ON NEXT 5M;
-- 创建分区表
CREATE TABLE ts_comp
(
id NUMERIC(6),
time_id DATE,
status VARCHAR(2)
)
PARTITION BY RANGE (time_id)
SUBPARTITION BY LIST (status)
(
PARTITION p1 VALUES LESS THAN ('2006-APR-01') TABLESPACE ts1
(
SUBPARTITION p1_a VALUES ('A1', 'A2'),
SUBPARTITION p1_b VALUES ('B1', 'B2', 'B3')
),
PARTITION p2 VALUES LESS THAN ('2006-JUL-01') TABLESPACE ts2
(
SUBPARTITION p2_a VALUES ('A1', 'A2'),
SUBPARTITION p2_b VALUES ('B1', 'B2', 'B3'),
SUBPARTITION p2_default VALUES (DEFAULT) TABLESPACE ts1
),
PARTITION p3 VALUES LESS THAN ('2006-OCT-01') TABLESPACE ts3
);
-- 删除表和表空间
DROP TABLE ts_comp CASCADE;
DROP TABLESPACE ts1;
DROP TABLESPACE ts2;
DROP TABLESPACE ts3;
这个例子有如下特点:
除了表空间物理属性,所有二级子分区表继承所有的物理属性,这是因为某些一级子分区表或二级子分区表已经指定表空间。没有指定表级别的物理属性,那么表空间级别默认被继承到所有的级别。
一级子分区表p1的2个二级子分区表存储在表空间ts1中。
一级子分区表p2的前2个二级子分区表存储在表空间ts2中,而p2_default存储在表空间ts1中。
一级子分区表p3没有二级子分区表,所以会为它默认创建一个DEFAULT二级子分区表存储在表空间ts3中,二级子分区表的名字由系统命名。
示例5:范围-范围复合分区表¶
范围-范围复合分区表的一级范围分区表和非复合分区表一样,可以使用PARTITION子句指定物理和其它属性,包括表空间、段等。如果没有指定分区级别,则分区表的就会继承主表的属性。
二级范围子分区表除了只能指定表空间物理属性外,其它和非复合分区范围表一样,二级范围子分区表继承主分区表的所有属性
-- 清理环境
DROP TABLE ts_comp;
-- 创建分区表
CREATE TABLE ts_comp
(
id NUMERIC(6),
order_date DATE,
delivery_date DATE
)
PARTITION BY RANGE (order_date)
SUBPARTITION BY RANGE (delivery_date)
(
PARTITION p_2006_jul VALUES LESS THAN ('2006-AUG-01')
(
SUBPARTITION p06_jul_e VALUES LESS THAN ('2006-AUG-15'),
SUBPARTITION p06_jul_a VALUES LESS THAN ('2006-SEP-01'),
SUBPARTITION p06_jul_l VALUES LESS THAN (MAXVALUE)
),
PARTITION p_2006_aug VALUES LESS THAN ('2006-SEP-01')
(
SUBPARTITION p06_aug_e VALUES LESS THAN ('2006-SEP-15'),
SUBPARTITION p06_aug_a VALUES LESS THAN ('2006-OCT-01'),
SUBPARTITION p06_aug_l VALUES LESS THAN (MAXVALUE)
)
);
-- 删除表和表空间
DROP TABLE ts_comp CASCADE;
检查一行数据行分区列的值决定它属于哪一个一级范围子分区表,然后再检查二级范围子分区表的子分区列值决定其属于哪一个二级范围子分区表。 例如:一个订单日期order_date在2006年8月,交付日期delivery_date在2006年09月28日,那么它属于二级子分区表p06_aug_a。
示例6:列表-哈希复合分区表¶
创建列表-哈希复合分区表ts_comp,列表分区使用status列,哈希分区使用id列
-- 清理环境
DROP TABLE ts_comp;
-- 创建分区表
CREATE TABLE ts_comp
(
id NUMERIC(6),
status VARCHAR(2)
)
PARTITION BY LIST (status)
SUBPARTITION BY HASH (id) SUBPARTITIONS 4
(
PARTITION p1 VALUES ('A1', 'A2'),
PARTITION p2 VALUES ('B1', 'B2', 'B3')
);
-- 删除表和表空间
DROP TABLE ts_comp CASCADE;
示例7:列表-列表复合分区表¶
创建列表-列表复合分区表ts_comp,第一次列表分区使用region列,第二次列表分区使用status列
-- 清理环境
DROP TABLE ts_comp;
-- 创建分区表
CREATE TABLE ts_comp
(
id NUMERIC(6),
region VARCHAR(2),
status VARCHAR(1))
PARTITION BY LIST (region)
SUBPARTITION BY LIST (status)
(
PARTITION p_southeast VALUES ('FL', 'GA')
(
SUBPARTITION p_se_bad VALUES ('B'),
SUBPARTITION p_se_average VALUES ('A'),
SUBPARTITION p_se_good VALUES ('G')
),
PARTITION p_northcentral VALUES ('SD', 'WI')
(
SUBPARTITION p_nc_bad VALUES ('B'),
SUBPARTITION p_nc_average VALUES ('A'),
SUBPARTITION p_nc_good VALUES ('G')
)
);
-- 删除表和表空间
DROP TABLE ts_comp CASCADE;
示例8:列表-范围复合分区表¶
创建列表-范围复合分区表ts_comp,列表分区使用status列,范围分区使用time_id列
-- 清理环境
DROP TABLE ts_comp;
-- 创建分区表
CREATE TABLE ts_comp
(
id NUMERIC(6),
time_id DATE,
status VARCHAR(2))
PARTITION BY LIST (status)
SUBPARTITION BY RANGE (time_id)
(
PARTITION p1 VALUES ('A1', 'A2')
(
SUBPARTITION p1_a VALUES LESS THAN ('2006-APR-01'),
SUBPARTITION p1_b VALUES LESS THAN ('2006-JUL-01')
),
PARTITION p2 VALUES ('B1', 'B2', 'B3')
(
SUBPARTITION p2_a VALUES LESS THAN ('2006-APR-01'),
SUBPARTITION p2_b VALUES LESS THAN ('2006-JUL-01')
)
);
-- 删除表和表空间
DROP TABLE ts_comp CASCADE;