使用多列分区键

对于范围分区和哈希分区,可以指定最多16个分区键。当分区键由多列组成,并且随后的几列比先前的列更加细化时使用多列分区。常见的细化情况像DATE和TIMESTAMP,由年、月和日几列组成。

在计算多列分区键时,只有当第一个值不能唯一标识单个目标分区时才使用第二个值,而当第一和第二个值都不能确定正确的分区时使用第三个值,以此类推。一个值不能确定一个正确的分区仅当一个分区界限等于该值并且下一个分区也拥有同样的分区界限的时候。第n列被计算只有当前面的n-1列的多列键值都等于一个分区的n-1个分区界限。如果对于一个分区所有的列值完全等于分区界限值,那么数据库将确定该元组不属于此分区,然后再计算下一个分区。

在非确定分区界限定义的情况下(连续的分区至少有一列有相同的标识值),分区界限列表值变成一个包含值,表示的是“小于或等于”界限值。这是和确定分区界限完全不同的,确定分区界限表示是“小于”界限值。

示例:范围分区表中多列分区键的使用

此例中将实际的DATE按年、月、日分成三列。分区的粒度为一个季度。

--  清理环境
DROP TABLE simple_sale;

-- 创建分区表
CREATE TABLE simple_sale
(
    year NUMBER,
    month NUMBER,
    day NUMBER,
    amount_sold NUMBER
)
PARTITION BY RANGE(year,month)
( 
    PARTITION before2010 VALUES LESS THAN(2010,1),
    PARTITION q1_2010 VALUES LESS THAN(2010,4),
    PARTITION q2_2010 VALUES LESS THAN(2010,7),
    PARTITION q3_2010 VALUES LESS THAN(2010,10),
    PARTITION q4_2010 VALUES LESS THAN(2011,1),
    PARTITION future VALUES LESS THAN(MAXVALUE,0)
);
--2009-12-12
INSERT INTO simple_sale VALUES(2009,12,12,1000);
--2010-3-17
INSERT INTO simple_sale VALUES(2010,3,17,2000);
--2010-11-1
INSERT INTO simple_sale VALUES(2010,11,1,5000);
--2011-1-1
INSERT INTO simple_sale VALUES(2011,1,1,4000);


--对于2009-12-12的年满足第一分区,before2010,所以不需要往后计算
SELECT *FROM simple_sale PARTITION(before2010);
YEAR(numeric)      |MONTH(numeric)      |DAY(numeric)      |AMOUNT_SOLD(numeric)      |
-----------------------------------------------------------------------------------
2009               |12                  |12                |1000                      |
总数目:1


--对于2010-3-17的元组则存储在分区q1_2010。 第一个键值year未能确定正确的分区,所以第二个分区键列month才被计算
SELECT *FROM simple_sale PARTITION(q1_2010);
YEAR(numeric)      |MONTH(numeric)      |DAY(numeric)      |AMOUNT_SOLD(numeric)      |
-----------------------------------------------------------------------------------
2010               |3                   |17                |2000                      |
总数目:1


--和前面的计算规则一样,由第二列month计算得出2010-11-1的元组属于q4_2010分区
SELECT *FROM simple_sale PARTITION(q4_2010);
YEAR(numeric)      |MONTH(numeric)      |DAY(numeric)      |AMOUNT_SOLD(numeric)      |
-----------------------------------------------------------------------------------
2010               |11                  |1                 |5000                      |
总数目:1


--对于日期2011-1-1则只计算year列就可以确定为future分区
SELECT *FROM simple_sale PARTITION(future);
YEAR(numeric)      |MONTH(numeric)      |DAY(numeric)      |AMOUNT_SOLD(numeric)      |
-----------------------------------------------------------------------------------
2011               |1                   |1                 |4000                      |
总数目:1

--  删除表
DROP TABLE simple_sale CASCADE;