【问题标题】:Oracle DB daily partitioningOracle DB 每日分区
【发布时间】:2013-08-09 17:45:03
【问题描述】:

我有下表

  CREATE TABLE "METRIC_VALUE_RAW" 
   (    
    "SUBELEMENT_ID" INTEGER NOT NULL , 
    "METRIC_METADATA_ID" INTEGER NOT NULL , 
    "METRIC_VALUE_INT" INTEGER, 
    "METRIC_VALUE_FLOAT" FLOAT(126), 
    "TIME_STAMP" TIMESTAMP  NOT NULL 
   ) ;
  1. 每小时数据将使用 sql loader 加载到表中。
  2. 我想创建分区,以便每天的数据进入一个分区。
  3. 我想在表中存储 30 天的数据。因此,当超过 30 天时,应该删除最旧的分区。

您能否分享您对我如何设计分区的想法。

【问题讨论】:

  • 在谈到分区自动化时,10g 和 11g 之间存在巨大差异,因此您需要说明您正在使用的版本。
  • 我使用的是 10g。由于我们计划将来升级,因此了解 11g 也会有所帮助。因此,了解两者都会有所帮助。

标签: oracle database-partitioning


【解决方案1】:

这是一个如何在 Oracle 11g 上执行此操作的示例,它运行良好。我在Oracle 10g上没试过,你可以试试。

就是这样,如何创建带有每日分区的表:

CREATE TABLE XXX (
    partition_date   DATE,
  ...,
  ...,
)
PARTITION BY RANGE (partition_date)
INTERVAL (NUMTODSINTERVAL(1, 'day'))
(
   PARTITION part_01 values LESS THAN (TO_DATE('2000-01-01','YYYY-MM-DD'))
)
TABLESPACE  MY_TABLESPACE
NOLOGGING;

正如您在上面看到的,Oracle 将在 2000 年 1 月 1 日之后自动为每个不同的 partition_day 创建单独的分区。partition_date 早于该日期的记录将存储在名为“part_01”的分区中。

您可以使用以下语句监控您的表分区:

SELECT * FROM user_tab_partitions WHERE table_name = 'XXX';

之后,当你想删除一些分区时,使用以下命令:

ALTER TABLE XXX DROP PARTITION AAAAAA UPDATE GLOBAL INDEXES

其中 'AAAAAA' 是分区名称。

希望对你有帮助!

【讨论】:

    【解决方案2】:

    正如我所说,10g 和 11g 之间的分区自动化存在很大差异。 在 10G 中,您将不得不在 ETL 过程中手动管理分区(我确信每个 10g DBA 都有他编写的用于管理分区的实用程序包......)。

    对于第 1 步和第 2 步,您有多种选择

    1. 将数据直接加载到日常分区中。
    2. 将数据加载到新分区中并将其合并到每日分区中。
    3. 每小时和在维护期间将数据加载到新分区中 窗口将所有小时分区合并为一个每日分区。

    适合您的方式取决于您的需求。新添加的数据是否立即被查询?以什么方式?您会跨几个小时(或加载...)查询数据吗?你在显示聚合吗?您是否对数据执行 DML 操作(对分区的 DDL 操作会导致大量锁定)。

    大约 3,再次 - 手动。删除旧分区。

    在 11G 中,您拥有新的间隔分区功能,可以自动执行上述一些任务。

    【讨论】:

      【解决方案3】:

      以下是创建分区数据的示例 sql:

      CREATE TABLE quarterly_report_status (
          report_id INT NOT NULL,
          report_status VARCHAR(20) NOT NULL,
          report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      )
      PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (
          PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ),
          PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-02 00:00:00') ),
          PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-03 00:00:00') ),
          PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-04 00:00:00') ),
          PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-05 00:00:00') ),
          PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-06 00:00:00') ),
          PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-07 00:00:00') ),
          PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-08 00:00:00') ),
          PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-09 00:00:00') ),
          PARTITION p9 VALUES LESS THAN (MAXVALUE)
      );
      

      分区将由 DBa 创建,其余部分将由 oracle 处理。 如果要删除分区,则必须为其编写单独的作业。

      【讨论】:

      • 这是一个 MySQL 的例子吗?
      • 感谢您的示例。在示例中,您指定了年份(2008/2009)。有没有办法在不指定日期的情况下创建每日分区,以便它们可重用。我想存储 30 天的数据。
      • @user2032118:那一年的差异是一个错误[我现在将更正它],一旦你像这样定义分区顺序,oracle 会继续在创建表脚本中使用相同的模式选择相关分区。您只需要不断添加分区即可。
      猜你喜欢
      • 1970-01-01
      • 2019-10-31
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      相关资源
      最近更新 更多