【问题标题】:Oracle Partition by ID and subpartition by DATE with intervalOracle 按 ID 分区和按 DATE 分区,间隔时间
【发布时间】:2016-03-05 21:14:46
【问题描述】:

我正在处理的架构有少量客户,每个客户都有大量数据。

在确定分区策略时,我的第一个想法是按 customer_id 分区,然后按天间隔按范围进行子分区。但是,您不能在子分区中使用间隔。

最终,我想要一种在新客户创建时自动为其创建分区的方法,并且还可以为客户的数据自动创建每日子分区。所有应用程序查询都在 customer_id 级别,并指定了各种日期范围。

这个post几乎一模一样,不过答案涉及到反转分区策略,我还是想找到一种方法来完成range-range区间分区。一种方法可能是每月进行一次数据库作业来为未来几天/几个月创建子分区,但这感觉不对。

也许我的假设是错误的,即当前数据结构将从范围-范围间隔分区策略中受益更多。我们有一些客户的数据让其他客户相形见绌,所以我在想办法隔离客户数据。

对更好的方法有什么想法/建议吗?

再次感谢您!

更新

这是我提出的一个例子:

    CREATE TABLE PART_TEST(
            CUSTOMER_ID NUMBER,
            LAST_MODIFIED_DATE DATE
        )
        PARTITION BY RANGE (CUSTOMER_ID) 
        INTERVAL (1) 
        SUBPARTITION BY RANGE (LAST_MODIFIED_DATE)
        SUBPARTITION TEMPLATE
         (
            SUBPARTITION subpart_1206_min values LESS THAN (TO_DATE('12/2006','MM/YYYY')),
            SUBPARTITION subpart_0107 values LESS THAN (TO_DATE('01/2007','MM/YYYY')),
            SUBPARTITION subpart_0207 values LESS THAN (TO_DATE('02/2007','MM/YYYY')),
            ...
            ...
            ...
            SUBPARTITION subpart_max values LESS THAN (MAXVALUE)
         )
         (
         PARTITION part_1 VALUES LESS THAN (1)
         )

我目前在模板中有 290 个子分区。除了一个障碍之外,这似乎是有效的。在我的测试中,我发现任何 CUSTOMER_ID 大于 3615 的记录都失败并出现 ORA-14400:插入的分区键未映射到任何分区

【问题讨论】:

  • 根据Logical Database Limits,您最多可以拥有 1'048'575 个分区。你有 290*3'615 = 1'048'350。我真的建议您修改分区计划!您希望表中有多少条记录?万亿?
  • 感谢 Wernfried,最终我只预计大约 2000 位客户,但就分区策略而言,这显然是过度的。数据库是一个多租户系统,我的目标是找到一种方法将每个客户数据划分为段以帮助提高性能等,因此我在 CUSTOMER_ID 级别进行分区,然后按月/年进行子分区的原因。

标签: database oracle oracle11g data-partitioning


【解决方案1】:

您可以在日期上创建RANGE INTERVAL 分区,然后在其上创建LISTRANGE 子分区。会是这样的:

CREATE TABLE MY_PART_TABLE
(
  CUSTOMER_ID                      NUMBER             NOT NULL,
  THE_DATE                 TIMESTAMP(0) NOT NULL,
  OTHER_COLUMNS NUMBER
)
PARTITION BY RANGE (THE_DATE) INTERVAL (INTERVAL '1' MONTH)
    SUBPARTITION BY RANGE (CUSTOMER_ID)
        SUBPARTITION TEMPLATE (
        SUBPARTITION CUSTOMER_GROUP_1 VALUES LESS THAN (10),
        SUBPARTITION CUSTOMER_GROUP_2 VALUES LESS THAN (20),
        SUBPARTITION CUSTOMER_GROUP_3 VALUES LESS THAN (30),
        SUBPARTITION CUSTOMER_GROUP_4 VALUES LESS THAN (40),
        SUBPARTITION CUSTOMER_GROUP_5 VALUES LESS THAN (MAXVALUE)
        )
(PARTITION VALUES LESS THAN ( TIMESTAMP '2015-01-01 00:00:00') );



CREATE TABLE MY_PART_TABLE
(
  CUSTOMER_ID                      NUMBER             NOT NULL,
  THE_DATE                 TIMESTAMP(0) NOT NULL,
  OTHER_COLUMNS NUMBER
)
PARTITION BY RANGE (THE_DATE) INTERVAL (INTERVAL '1' MONTH)
    SUBPARTITION BY LIST (CUSTOMER_ID)
        SUBPARTITION TEMPLATE (
        SUBPARTITION CUSTOMER_1 VALUES (1),
        SUBPARTITION CUSTOMER_2 VALUES (2),
        SUBPARTITION CUSTOMER_3_to_6 VALUES (3,4,5,6),
        SUBPARTITION CUSTOMER_7 VALUES (7)
        )
(PARTITION VALUES LESS THAN ( TIMESTAMP '2015-01-01 00:00:00') );

注意,对于第二种解决方案,客户的数量(即 ID)是固定的。如果您有新客户,您必须更改表并相应地修改 SUBPARTITION TEMPLATE。

每当插入或更新新值时,Oracle 都会自动创建每月分区。

【讨论】:

  • 谢谢。这类似于我上面发布的链接中的解决方案。但是,我认为仍然不能与我拥有的数据一起使用。我宁愿找到一个主要在 CUSTOMER_ID 上进行分区,然后在 DAY 上进行子分区的解决方案。很可能我会有几个月的子分区模板等。
  • 我不建议这样做,您会失去 INTERVAL 分区的强大功能,Oracle 会在需要时自动创建新分区(包括子分区)。
  • 我仍然计划在 CUSTOMER_ID 上使用间隔分区和带有子分区模板的 INTERVAL(1)。这样,每次创建新客户时,都会创建一个新分区以及月份的子分区。我可以用这个示例更新问题...
  • 使用CUSTOMER_ID 分区时要小心并测试性能和可维护性——分区并不总是意味着更快。
猜你喜欢
  • 1970-01-01
  • 2018-09-24
  • 1970-01-01
  • 2016-01-14
  • 2016-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多