MaxCompute は、データインジェスト時間に基づいてテーブルを自動的にパーティショニングできます。これらのテーブルはインジェスト時間パーティションテーブルと呼ばれ、MaxCompute はインジェスト時間をキャプチャし、`TRUNC_TIME` などの指定された時間関数を使用してパーティションキー列の値を生成します。このトピックでは、これらのテーブルの使用方法について説明します。
機能
MaxCompute は、標準パーティションテーブルと自動パーティションテーブルの 2 種類のパーティションテーブルを提供します。シナリオに応じてパーティションキー列を生成する方法に基づいて、テーブルタイプを選択できます。詳細については、「パーティションテーブルの概要」をご参照ください。
インジェスト時間パーティションテーブルを使用するには、テーブル定義で、_partitiontime という名前の疑似列に時間ベースのデータの型を指定する必要があります。システムは、各行のインジェスト時間を時間、日、月、年などの特定の時間の粒度に切り捨て、その切り捨てられた時間を使用して _partitiontime 疑似列の値を自動的に生成します。
例えば、時間単位でパーティションを生成するインジェスト時間パーティションテーブルを作成し、次の時間にデータを書き込む場合:
データインジェスト時間 (UTC+8) | 生成された _PARTITIONTIME 列 (TIMESTAMP) | 生成されたパーティション (STRING) |
2025-06-18 17:22:00 | 2025-06-18 17:00:00 | 2025-06-18 09:00:00 |
2025-06-18 17:40:00 | 2025-06-18 17:00:00 | 2025-06-18 09:00:00 |
2025-06-18 18:31:00 | 2025-06-18 18:00:00 | 2025-06-18 10:00:00 |
前の例では、インジェスト時間パーティションテーブルは時間単位でパーティションを生成します。システムはデータインジェスト時間を切り捨てて _partitiontime 列に設定します。この値は UTC 文字列に変換され、パーティションキー列の値として使用されます。
制限事項
インジェスト時間パーティションテーブルは、単一のパーティションキー列のみをサポートします。複数レベルのパーティショニングはサポートされていません。
インジェスト時間パーティションテーブルのパーティションキー列のデフォルトのデータ型は STRING です。このデータ型は変更できません。
時間関数とデータインジェスト時間に基づく自動パーティショニング機能は、MaxCompute SQL を使用したデータ書き込みでのみサポートされます。Flink コネクタなどの他のデータインジェスト方法はサポートされていません。
インジェスト時間を切り捨てる場合、TRUNC_TIME 関数のみがサポートされています。この関数は、値を切り捨てる前にローカル時間を UTC に変換します。この変換により、タイムゾーンが STRING パーティションキー列の最終的な値に影響します。
SET odps.sql.timezone=UTC;文を実行して、プロジェクトのタイムゾーンを UTC に設定してください。
使用方法
インジェスト時間パーティションテーブルの作成
構文
次の構文を使用して、インジェスト時間パーティションテーブルを作成します。
CREATE [OR REPLACE] TABLE [IF NOT EXISTS] <table_name> (_partitiontime <data_type>, <col_name><data_type>... )
[COMMENT <table_comment>]
AUTO PARTITIONED BY (<auto_partition_expression> [AS <auto_partition_column_name>]);
TBLPROPERTIES('ingestion_time_partition'='true');パラメータ:
パラメータ | 必須 | 説明 |
table_name | はい | 作成するテーブルの名前。 |
_partitiontime | はい | 切り捨てられたインジェスト時間のための疑似列。列名は変更できません。サポートされているデータ型は TIMESTAMP と TIMESTAMP_NTZ です。 |
col_name | はい | 列名。 |
data_type | はい | 列のデータ型。 |
table_comment | いいえ | テーブルのコメント。 |
TBLPROPERTIES('ingestion_time_partition'='true') | はい | 作成するテーブルがインジェスト時間パーティションテーブルであることを指定します。パーティションキー列は、データインジェスト時間に基づいて生成されます。 |
auto_partition_expression | はい | パーティションキー列の計算を定義する式。現在、TRUNC_TIME 関数を使用して 説明 インジェスト時間パーティションテーブルを作成すると、システムは自動的にデータインジェスト時間を取得します。その後、TRUNC_TIME 関数を使用してこの時間を切り捨て、パーティションキー列の値を生成します。 |
auto_partition_column_name | いいえ | 生成されるパーティションキー列の名前です。名前を指定しない場合、システムはデフォルト名として 説明 パーティション式が計算された後、結果に基づいて STRING 型のパーティションキー列が生成されます。この列のデータ型や値を直接変更することはできません。 |
例
例 1
この例では、時間単位でパーティション分割される
ingestion_sale_detail_hourlyという名前のインジェスト時間パーティションテーブルを作成します。テーブル定義では、TIMESTAMP 型の_partitiontimeという名前の疑似列を指定します。データがテーブルに書き込まれると、システムは自動的にデータのインジェスト時間を取得します。次に、DDL 文で指定された時間単位の粒度に基づいて、_partitiontime疑似列に値を設定します。その後、この結果に基づいてパーティションキー列sale_timeの値が生成されます。-- テーブル作成後、データ書き込み時にシステムが自動的にデータインジェスト時間を取得します。_partitiontime を時間単位で切り捨て、sale_time という名前のパーティションキー列を生成し、この列に基づいてテーブルをパーティション分割します。 CREATE TABLE IF NOT EXISTS ingestion_sale_detail_hourly( shop_name STRING, total_price DOUBLE, _partitiontime TIMESTAMP) AUTO PARTITIONED BY (TRUNC_TIME(_partitiontime, 'hour') AS sale_time) TBLPROPERTIES('ingestion_time_partition'='true');前の例で作成された
ingestion_sale_detail_hourlyテーブルには 4 つの列が含まれています。sale_time列は、STRING 型の自動的に生成されたパーティションキー列です。DESC ingestion_sale_detail_hourly;文を実行して、テーブル情報を表示できます。以下に結果の例を示します。+------------------------------------------------------------------------------------+ | Owner: ALIYUN$test**** | | Project: xxxxxxx | | Schema: default | | TableComment: | +------------------------------------------------------------------------------------+ | CreateTime: 2025-06-16 14:59:40 | | LastDDLTime: 2025-06-16 14:59:40 | | LastModifiedTime: 2025-06-16 14:59:40 | +------------------------------------------------------------------------------------+ | InternalTable: YES | Size: 0 | +------------------------------------------------------------------------------------+ | Native Columns: | +------------------------------------------------------------------------------------+ | Field | Type | Label | Comment | +------------------------------------------------------------------------------------+ | shop_name | string | | | | | total_price | double | | | | _partitiontime | timestamp | | | +------------------------------------------------------------------------------------+ | Partition Columns: | +------------------------------------------------------------------------------------+ | sale_time | string | | +------------------------------------------------------------------------------------+例 2
この例では、日単位でパーティション分割された
ingestion_sale_detail_dailyという名前の取り込み時間パーティションテーブルを作成します。パーティションの粒度が日単位の場合、_partitiontime疑似列に加えて、DATE 型の_partitiondateという疑似列も生成されます。CREATE TABLE IF NOT EXISTS ingestion_sale_detail_daily( shop_name STRING, total_price DOUBLE, _partitiontime TIMESTAMP) AUTO PARTITIONED BY (TRUNC_TIME(_partitiontime, 'day') AS sale_date) TBLPROPERTIES('ingestion_time_partition'='true');説明SELECT *, _partitiondate FROM ingestion_sale_detail_daily;コマンドを実行して、_partitiondate疑似列を表示できます。インジェスト時間パーティションキー列のパーティション生成ロジックを表示するには、SHOW CREATE TABLE 文を使用できます。
インジェスト時間パーティションテーブルへのデータ書き込み
SQL 文を使用して取り込み時間パーティションテーブルにデータを書き込む場合、_partitiontime 疑似列の値を指定できます。ただし、_partitiontime の値の時間粒度は、`CREATE TABLE` 文で定義された粒度と一致させる必要があります。
_partitiontime の値を指定しない場合、システムはデータが MaxCompute に書き込まれる時間を自動的に使用します。その後、指定された時間関数を使用して _partitiontime 疑似列に入力してパーティションキー列の値を生成し、それに応じてデータをパーティション分割します。
例:
以下の例では、例 セクションで作成された ingestion_sale_detail_hourly テーブルと ingestion_sale_detail_daily テーブルにデータを書き込む方法について説明します。
例 1
データを挿入する際は、
_partitiontime疑似列の値を指定しないでください。INSERT INTO ingestion_sale_detail_hourly (shop_name,total_price) VALUES ('shanghai_shop',10001.1), ('chongqin_shop',20002.2), ('hangzhou_shop',30003.3), ('shenzhen_shop',40004.4);例 2
データを挿入する際、
_partitiontime疑似列に値を指定できます。_partitiontimeの値の時間粒度は、指定されたパーティションの粒度 (`hour`) と一致する必要があります。有効な例:
_partitiontime列の値に'2025-06-15 14:00:00'を指定します。INSERT INTO ingestion_sale_detail_hourly (shop_name,total_price,_partitiontime) VALUES ('beijing_shop',50005.5,TIMESTAMP '2025-06-15 14:00:00'), ('chengdu_shop',60006.6,TIMESTAMP '2025-06-14 05:00:00');不正な例:
_partitiontime列の値として'2025-06-15 14:30:00'を指定します。 この値は、時間単位のパーティション粒度と一致しません。INSERT INTO ingestion_sale_detail_hourly (shop_name,total_price,_partitiontime) VALUES ('beijing_shop',50005.5,TIMESTAMP '2025-06-15 14:30:00');次のエラーメッセージが返されます:
FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: SQL Runtime Unretryable Error: ODPS-0121095:Invalid argument - illegal ingestion time: 2025-06-15 14:30:00
例 3
パーティション粒度が日単位の場合、
_partitiontime疑似列にのみ値を指定できます。_partitiondate疑似列には値を指定できません。有効な例:
_partitiontime列の値に'2025-06-18 00:00:00'を指定します。INSERT INTO ingestion_sale_detail_daily (shop_name,total_price,_partitiontime) VALUES ('beijing_shop',50005.5,TIMESTAMP '2025-06-18 00:00:00');無効な例:
_partitiontime列の値として'2025-06-15 14:00:00'を指定します。この値は、日単位のパーティション粒度と一致しません。INSERT INTO ingestion_sale_detail_daily (shop_name,total_price,_partitiontime) VALUES ('beijing_shop',50005.5,TIMESTAMP '2025-06-18 14:00:00');次のエラーメッセージが返されます:
FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: SQL Runtime Unretryable Error: ODPS-0121095:Invalid argument - illegal ingestion time: 2025-06-18 14:00:00直接
_partitiondate疑似列に値を指定します。INSERT INTO ingestion_sale_detail_daily (shop_name,total_price,_partitiondate) VALUES ('beijing_shop',50005.5,DATE '2025-06-15');次のエラーメッセージが返されます:
FAILED: ODPS-0130071:[1,64] Semantic analysis exception - column _partitiondate cannot be resolved; Did you mean _partitiontime ?
インジェスト時間パーティションテーブルのクエリ
SELECT *クエリを実行した場合、デフォルトでは_partitiontimeまたは_partitiondate疑似列、あるいは生成されたパーティションキー列は返されません。これらの列を表示するには、たとえばSELECT *, _partitiontime FROM xxx;のように、文で明示的に指定する必要があります。時間、月、または年でパーティション化されたテーブルでは、クエリのフィルタリングとパーティションプルーニングに
_partitiontime疑似列を使用できます。取り込み時間パーティションテーブルは、自動パーティションテーブルの特殊なタイプです。標準の自動パーティションテーブルと同じパーティションプルーニング機能をサポートします。詳細については、「時間関数に基づく自動パーティションテーブル」をご参照ください。
例:
以下の例では、「例」セクションで作成された ingestion_sale_detail_hourly および ingestion_sale_detail_daily テーブルからデータをクエリする方法を示します。
例 1
SELECT *クエリを実行すると、デフォルトでは_partitiontimeや_partitiondate疑似列、または生成されたパーティションキー列は返されません。SELECT * FROM ingestion_sale_detail_hourly; -- 結果が返されます。 +------------+-------------+ | shop_name | total_price | +---------------+-------------+ | shanghai_shop | 10001.1 | | chongqin_shop | 20002.2 | | hangzhou_shop | 30003.3 | | shenzhen_shop | 40004.4 | | chengdu_shop | 60006.6 | | beijing_shop | 50005.5 | +---------------+-------------+例 2
クエリで
_partitiontimeまたは_partitiondate擬似列および生成されたパーティションキー列を指定できます。この例では、sale_timeとsale_dateは、テーブルの作成時に指定されたパーティションキー列の名前です。説明この例では、
set odps.sql.timezone=Asia/Shanghai;コマンドを実行して、プロジェクトのローカルタイムゾーンを `Asia/Shanghai` (UTC + 08:00) に設定します。このタイムゾーンは、`TRUNC_TIME` 関数によって生成されるパーティション値に影響します。時間単位でパーティション化されている
ingestion_sale_detail_hourlyテーブルをクエリします。SELECT * ,_partitiontime,sale_time FROM ingestion_sale_detail_hourly; --次の結果が返されます: +---------------+-------------+---------------------+---------------------+ | shop_name | total_price | _partitiontime | sale_time | +---------------+-------------+---------------------+---------------------+ | shanghai_shop | 10001.1 | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 | | chongqin_shop | 20002.2 | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 | | hangzhou_shop | 30003.3 | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 | | shenzhen_shop | 40004.4 | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 | | beijing_shop | 50005.5 | 2025-06-15 14:00:00 | 2025-06-15 06:00:00 | | chengdu_shop | 60006.6 | 2025-06-14 05:00:00 | 2025-06-13 21:00:00 | +---------------+-------------+---------------------+---------------------+日単位でパーティション化された
ingestion_sale_detail_dailyテーブルをクエリします。SELECT * ,_partitiontime,_partitiondate,sale_date FROM ingestion_sale_detail_daily; --次の結果が返されます: +--------------+-------------+---------------------+----------------+-----------+ | shop_name | total_price | _partitiontime | _partitiondate | sale_date | +--------------+-------------+---------------------+----------------+-----------+ | beijing_shop | 50005.5 | 2025-06-18 00:00:00 | 2025-06-18 | 2025-06-18| +--------------+-------------+---------------------+----------------+-----------+