我可以使用 default/maxvalue 分区创建一个不断增长的间隔分区 table 吗?

Can I create a growing Interval partitioned table with a default/maxvalue partition?

问题摘要:创建 table 具有范围分区的分区。然而,不知道范围值的记录应该驻留在不同的(默认)分区中,并在填充值时移动到正确的分区。默认分区永远不会被删除,而其他分区将在定义的保留期后通过脚本删除。

整个故事:

我有一个 table,其中记录必须放置在基于日期字段的分区中。这是一个不断增长的 table,一段时间后可以清除这些分区中的数据。我曾经使用类似下面的代码片段创建 table。

这很好用,因为我们知道分区所依据的日期列的值 (RDATE)。然而,在我们的新项目中,插入记录时我们并不知道这一点。该值最终将在申请处理过程中填写。

我最初的想法是创建 MAXPARTITION (MAXVALUE),它将成为未填写日期的记录的全能分区,并启用 ROW MOVEMENTS,以便在填写日期时将其移动到适当的分区中。但是我认为不可能同时具有 MAXVALUE 分区和间隔分区。是吗?

另外还有更好的方法吗?

PARTITION BY RANGE ("RDATE") INTERVAL (NUMTODSINTERVAL (1,'DAY')) 
SUBPARTITION BY HASH ("RKEY") 
SUBPARTITION TEMPLATE ( 
   SUBPARTITION "SP01", 
   SUBPARTITION "SP02", 
   SUBPARTITION "SP03", 
   SUBPARTITION "SP04", 
   SUBPARTITION "SP05", 
   SUBPARTITION "SP06", 
   SUBPARTITION "SP07", 
   SUBPARTITION "SP08", 
   SUBPARTITION "SP09", 
   SUBPARTITION "SP10", 
   SUBPARTITION "SP11", 
   SUBPARTITION "SP12", 
   SUBPARTITION "SP13", 
   SUBPARTITION "SP14", 
   SUBPARTITION "SP15", 
   SUBPARTITION "SP16" ) 
(PARTITION "INITIALPARTITION"  VALUES LESS THAN (TO_DATE(' 2016-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) 

我希望 table 具有默认和范围分区以及记录,以便在列被填充时从默认移动到范围分区。

您用作分区键的列不能为 NULL,但您可以使用如下解决方法:

CREATE TABLE ... (
    ...
    RDATE DATE,
    PARTITION_KEY DATE GENERATED ALWAYS AS (COALESCE(RDATE, DATE '1969-12-31')) 
)
PARTITION BY RANGE (PARTITION_KEY) INTERVAL (NUMTODSINTERVAL (1,'DAY'))
...
(PARTITION INITIAL_PARTITION VALUES LESS THAN (DATE '1970-01-01'))
ENABLE ROW MOVEMENT;

如果您使用 RDATE = NULL 插入一条记录,那么它将被插入分区 INITIAL_PARTITION。对于初始数据(例如 1970-01-01),您必须 select 一个永远不会落入 "real" 日期值的值。您也可以使用遥远未来的日期,例如

CREATE TABLE ... (
    ...
    RDATE DATE,
    PARTITION_KEY DATE GENERATED ALWAYS AS (COALESCE(RDATE, DATE '2999-12-31')) 
)
PARTITION BY RANGE (PARTITION_KEY) INTERVAL (NUMTODSINTERVAL (1,'DAY'))
...
(PARTITION INITIAL_PARTITION VALUES LESS THAN (DATE '2019-04-01'))
ENABLE ROW MOVEMENT;

-- Create DEFAULT_PARTITION
INSERT INTO ... (RDATE) VALUES (NULL);
ROLLBACK;
ALTER TABLE ... RENAME PARTITION FOR (TIMESTAMP '2999-12-31 00:00:00') TO DEFAULT_PARTITION;