问题的摘要:用范围分区的分区创建表。但是,不知道范围值的记录应驻留在其他(默认)分区中,并在填充值时将其移至正确的分区。在定义的保留期限之后,将通过脚本删除默认分区,而将其他分区删除。
整个故事:
我有一个表,其中必须根据日期字段将记录放置在分区中。这是一个增长中的表,一段时间后可以清除这些分区中的数据。我以前用下面的代码片段创建表。
这很好用,因为我们知道划分日期(RDATE)所依据的date列的值。但是,在我们的新项目中,插入记录时我们并不知道这一点。该值最终将在申请处理过程中填写。
我最初的想法是创建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'))
我希望具有默认分区和范围分区以及记录的表在填充列时将从默认分区移到范围分区。
答案 0 :(得分:1)
用作分区键的列不能为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),您必须选择一个值,该值应不会落入“实际”日期值中。您也可以在将来使用日期,例如
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;