すべてのプロダクト
Search
ドキュメントセンター

PolarDB:間隔範囲の分割

最終更新日:Aug 23, 2024

PolarDB for PostgreSQL (Oracle互換) は、間隔によるテーブルのパーティション分割をサポートしています。 このトピックでは、間隔範囲分割の構文について説明し、例での使用方法について説明します。

概要

PolarDB for PostgreSQL (Compatible with Oracle) は、パーティションの自動作成を可能にする間隔範囲パーティション分割をサポートしています。 間隔は、レンジパーティションテーブルを作成するときに定義されます。 新しいデータが既存のパーティションの範囲内にない場合、PolarDB for PostgreSQL (Compatible with Oracle) は自動的に新しいパーティションを作成します。

間隔範囲分割は、範囲分割の拡張です。 既存のパーティションの時間範囲に属さない新しいデータが到着すると、データベースはデータを保持する新しいパーティションを自動的に作成します。 間隔範囲パーティション分割を実装するには、interval句を使用し、新しいパーティションの時間間隔を指定します。 パーティションキーは、指定された間隔で新しいパーティションが作成される高い値または遷移ポイントを決定します。

間隔範囲分割テーブルでは、時間間隔が1か月に設定され、最新のパーティションが2か月前であると仮定します。 新しいデータが到着すると、データベースはデータを保持するために現在の月のパーティションのみを作成します。 その間の月のパーティションをスキップします。 例えば、最新のパーティションの時間範囲が1月15日から2月15日であると仮定する。 5月10日からのデータがテーブルに挿入されると、データベースはデータを保持するために4月15日から5月15日までのパーティションを作成し、2月15日から3月15日、3月15日から4月15日までのパーティションの作成はスキップします。

制限事項

INTERVAL句には次の制限が適用されます。

  • 指定できるパーティションキー列は1つだけで、タイプは数値または日付範囲に制限されています。

  • 少なくとも1つのレンジパーティションを定義する必要があります。

  • マルチレベル分割では、インターバル分割を一次分割戦略として使用することができる。 サブパーティショニングには使用できません。

  • インデックス編成されたテーブルには間隔パーティションを使用できません。

  • リストパーティションテーブルにドメインインデックスを作成することはできません。

  • DEFAULTまたはMAXVALUEパーティションは、間隔パーティションテーブルに対して定義できません。

  • パーティションキー列は、NULL、not-a-Number、またはInfinityの値をサポートしていません。

  • 区間分割式は、負でない定数値を生成する必要があります。

  • 区間パーティションは昇順でのみ作成できます。

構文

CREATE TABLE [ schema. ]<table_name>
   <table_definition>
   PARTITION BY RANGE(<column>[, <column> ]...)
   [INTERVAL (<constant> | <expression>)]
   [SUBPARTITION BY {RANGE|LIST|HASH} (<column>[, <column> ]...)]
   (<range_partition_definition>[, <range_partition_definition>]...)
   [ENABLE ROW MOVEMENT];
WHERE range_partition_definition IS:
      PARTITION [<partition_name>]
        VALUES LESS THAN (<value>[, <value>]...)
        [TABLESPACE <tablespace_name>]
        [(<subpartition>, ...)]

INTERVALパラメーターは、数値と時間間隔のみをサポートします。

  • 数値インターバル

    1つのパーティションに10個の隣接する番号ごとに配置する:

    INTERVAL (10)
  • 時間間隔

    • 年ごとの自動パーティショニングの設定:

      INTERVAL (NUMTOYMINTERVAL(1,'year'))
    • 月ごとに自動パーティションを設定する:

      INTERVAL (NUMTOYMINTERVAL(1,'month'))
    • 日ごとに自動パーティションを設定する:

      INTERVAL (NUMTODSINTERVAL(1,'day'))
    • 週ごとに自動パーティションを設定する:

      INTERVAL (NUMTODSINTERVAL(7,'day'))

その他のパラメーターについては、「CREATE TABLE...PARTITION BY」をご参照ください。

この例では、salesテーブルは、sold_moth列で間隔範囲分割されています。 テーブルを区分する間隔範囲の目的は、遷移点を作成することであり、その上に新しい区分が自動的に作成される。

間隔範囲分割テーブルを作成し、テーブルにデータを挿入します。

CREATE TABLE sales
(
  prod_id           int,
  prod_quantity     int,
  sold_month        date
)
PARTITION BY RANGE(sold_month)
INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
(
  PARTITION p1
    VALUES LESS THAN('15-JAN-2019'),
  PARTITION p2
    VALUES LESS THAN('15-FEB-2019')
);

-- Query the ALL_TAB_PARTITIONS view.
SELECT partition_name, high_value from ALL_TAB_PARTITIONS;
 partition_name |      high_value
----------------+----------------------
 P1             | '15-JAN-19 00:00:00'
 P2             | '15-FEB-19 00:00:00'
(2 rows)

-- Insert data from a date above the transition point.
INSERT INTO sales VALUES (1,200,'10-MAY-2019');
INSERT 0 1

-- Data is inserted, and a new partition with a system-generated name is created to hold it. The partition name varies based on sessions.
SELECT partition_name, high_value FROM ALL_TAB_PARTITIONS;
 partition_name |      high_value
----------------+----------------------
 P1             | '15-JAN-19 00:00:00'
 P2             | '15-FEB-19 00:00:00'
 SYS916340103   | '15-MAY-19 00:00:00'
(3 rows)

レンジパーティションテーブルとインターバルレンジパーティションテーブルの間の変換

レンジパーティションテーブルをインターバルレンジパーティションテーブルに変換

範囲分割テーブルを間隔範囲分割テーブルに変換するには、ALTER TABLE...SET INTERVALを使用します。

範囲または時間間隔を設定すると、データベースは指定された範囲または時間間隔に基づいてパーティションを自動的に作成します。 次に、データが新しいパーティションに挿入されます。

構文は次のとおりです。

ALTER TABLE <table_name> SET INTERVAL (<constant> | <expression>);

間隔範囲パーティションテーブルを範囲パーティションテーブルに変換

SET INTERVAL() コマンドを実行して、間隔範囲のパーティショニングを無効にします。 インターバル範囲パーティション分割を無効にすると、データベースは、インターバル範囲パーティション分割テーブルを範囲パーティション分割テーブルに変換します。

構文は次のとおりです。

ALTER TABLE <table_name> SET INTERVAL ();

この例では、売上テーブルの分割スキームは、範囲分割から間隔範囲分割に変更されます。

-- Create a range-partitioned table named sales.
CREATE TABLE sales
(
  prod_id           int,
  prod_quantity     int,
  sold_month        date
)
PARTITION BY RANGE(sold_month)
(
  PARTITION p1
    VALUES LESS THAN('15-JAN-2019'),
  PARTITION p2
    VALUES LESS THAN('15-FEB-2019')
);

-- Query the ALL_TAB_PARTITIONS view.
SELECT partition_name, high_value FROM ALL_TAB_PARTITIONS;
 partition_name |      high_value
----------------+----------------------
 P1             | FOR VALUES FROM ('15-JAN-19 00:00:00') TO ('15-FEB-19 00:00:00')
 P2             | FOR VALUES FROM (MINVALUE) TO ('15-JAN-19 00:00:00')
(2 rows)

-- Convert the sales table into an interval range-partitioned table.
ALTER TABLE sales SET INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'));

-- Insert data beyond the time range of existing partitions.
INSERT INTO sales VALUES (1,100,'05-APR-2019');
INSERT 0 1

SELECT partition_name, high_value FROM ALL_TAB_PARTITIONS;
 partition_name |      high_value
----------------+----------------------
 SYS596430103   | FOR VALUES FROM ('15-MAR-19 00:00:00') TO ('15-APR-19 00:00:00')
 P1             | FOR VALUES FROM ('15-JAN-19 00:00:00') TO ('15-FEB-19 00:00:00')
 P2             | FOR VALUES FROM (MINVALUE) TO ('15-JAN-19 00:00:00')
(3 rows)