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

Hologres:動的テーブルの作成

最終更新日:Sep 03, 2026

ベーステーブルのクエリ結果を増分更新または完全更新を使用して自動的に更新する動的テーブルを作成します。

注意事項

  • 動的テーブルの使用制限:動的テーブルのサポートと制限事項。

  • Hologres V3.1 以降では、動的テーブルの作成に新しい構文が必要です。V3.0 の構文で作成されたテーブルに対しては引き続き ALTER 操作を実行できますが、新しく作成することはできません。非パーティションテーブルの場合、構文変換コマンドを使用してレガシ構文を新しい構文に変換できます。パーティションテーブルの場合は、手動で再作成してください。

  • Hologres V3.1 以降にアップグレードする場合、既存の増分動的テーブルを再作成する必要があります。その際には構文変換コマンドを使用できます。

  • Hologres V3.1 以降では、エンジンが更新プロセスを適応的に最適化します。更新操作に対して負のクエリ ID が表示されるのは想定内の動作です。

構文

V3.1+ (新しい構文)

説明

V3.1 以降は新しい構文のみをサポートします。

動的テーブル作成の構文

V3.1 以降で動的テーブルを作成するための構文:

CREATE DYNAMIC TABLE [ IF NOT EXISTS ] [<schema_name>.]<table_name>
[ (<col_name> [, ...] ) ]
[LOGICAL PARTITION BY LIST(<partition_key>)]
WITH (
  -- 動的テーブルのプロパティ
  freshness = {'<num> {minutes | hours}' | 'upstream'}, -- 必須
  [auto_refresh_enable = {true | false},] -- オプション
  [auto_refresh_mode = {'full' | 'incremental' | 'auto'},] -- オプション
  
  [base_table_cdc_format = {'stream' | 'binlog'},] -- オプション

  [auto_refresh_partition_active_time = '<num> {minutes | hours | days}',] -- オプション
  [partition_key_time_format = {'YYYYMMDDHH24' | 'YYYY-MM-DD-HH24' | 'YYYY-MM-DD_HH24' | 'YYYYMMDD' | 'YYYY-MM-DD' | 'YYYYMM' | 'YYYY-MM' | 'YYYY'},] --オプション
  
  [computing_resource = {'local' | 'serverless' | '<warehouse_name>'},] -- オプション。warehouse_name の値は Hologres V4.0.7 以降でのみサポートされます。
  [refresh_guc_hg_experimental_serverless_computing_required_cores=xxx,] --オプション。サーバーレスに必要なコンピューティングコアを指定します。
  
  [refresh_guc_<guc_name> = '<guc_value>',] -- オプション

  -- 一般的なプロパティ
  [orientation = {'column' | 'row' | 'row,column'},]
  [table_group = '<tableGroupName>',]
  [distribution_key = '<columnName>[,...]]',]
  [clustering_key = '<columnName>[:asc] [,...]',]
  [event_time_column = '<columnName> [,...]',]
  [bitmap_columns = '<columnName> [,...]',]
  [dictionary_encoding_columns = '<columnName> [,...]',]
  [time_to_live_in_seconds = '<non_negative_literal>',]
  [storage_mode = {'hot' | 'cold'},]
)
AS
<query>; -- クエリ定義。

パラメーター

更新モードとリソース

パラメーター

説明

必須

デフォルト

freshness

ターゲットデータの新鮮さを分または時間単位で指定します。最小値は 1 分です。エンジンは、前回の更新時間とこの freshness の値に基づいて更新をスケジュールします。固定間隔とは異なり、freshness はデータを可能な限り最新の状態に保つために自動的に適応します。有効な値:

  • '<num> {minutes | hours}':指定された新鮮さに基づいて更新が自動的にスケジュールされます。

  • 'upstream':カスケード更新モード。Hologres V5.0 以降でサポートされています。テーブル自体には更新スケジュールがありません。代わりに、上流の動的テーブルの更新が完了した後にトリガーされます。これにより、各レイヤーに個別の更新間隔を設定することなく、多層ウェアハウス (ODS から DWD、DWS、ADS へ) を通じてデータがレイヤーごとに流れることができます。この値を使用する場合、ベーステーブルの少なくとも 1 つが動的テーブルである必要があります。そうでない場合、テーブルの作成は失敗します。トリガーの動作については、「カスケード更新」をご参照ください。

はい

なし

auto_refresh_mode

更新モード。有効な値:

  • auto:自動モード。クエリがサポートしている場合、エンジンは自動的に増分更新を使用します。そうでない場合は、完全更新にフォールバックします。

  • incremental:増分更新。毎回増分データのみが更新されます。詳細については、「増分更新」をご参照ください。

  • full:完全更新。毎回テーブル全体が更新されます。詳細については、「完全更新」をご参照ください。

いいえ

auto

auto_refresh_enable

自動更新を有効または無効にします。有効な値:

  • true:自動更新を有効にします。

  • false:自動更新を無効にします。テーブルに対する後続のすべての更新ジョブが停止します。

いいえ

true

base_table_cdc_format

増分更新中にベーステーブルのデータ変更をどのように消費するか。

  • stream (デフォルト):ファイルレベルのデータ変更を読み取ります。追加のストレージオーバーヘッドがなく、binlog よりも高いパフォーマンスを発揮します。詳細については、「動的テーブル」をご参照ください。

  • binlog:binlog を介してベーステーブルのデータ変更を消費します。ベーステーブルで手動で binlog を有効にする必要があります (Hologres Binlog のサブスクライブ)。

    begin;
    call set_table_property('<table_name>', 'binlog.level', 'replica');
    call set_table_property('<table_name>', 'binlog.ttl', '2592000');
    commit;
説明
  • V3.1 から、すべてのテーブルはデフォルトで stream になります。不要なストレージコストを避けるために、有効になっている場合は binlog を無効にしてください。

  • stream メソッドは行指向のベーステーブルではサポートされておらず、binlog メソッドのみがサポートされています。

  • このパラメーターはテーブル作成後に変更できません。変更するには、テーブルを再作成してください。

いいえ

stream

computing_resource

更新用のコンピューティングリソース。有効な値:

  • serverless (デフォルト):サーバーレスコンピューティングリソースを使用し、更新ワークロードをクエリトラフィックから分離します。

  • <warehouse_name>:更新に指定されたコンピューティングウェアハウスを使用します。

    説明

    Hologres V4.0.7 以降でのみサポートされています。

  • local:更新に現在のインスタンスのローカルコンピューティングリソースを使用します。

パラメーター。

いいえ

serverless

refresh_guc_<guc_name>

更新用の GUC パラメーターを設定します。サポートされている GUC については、「GUC パラメーター」をご参照ください。

いいえ

なし

パーティションテーブル

論理パーティションテーブル

パラメーター

説明

必須

デフォルト

LOGICAL PARTITION BY LIST(<partition_key>)

論理パーティション化された動的テーブルを作成します。auto_refresh_partition_active_time と partition_key_time_format が必要です。

いいえ

なし

auto_refresh_partition_active_time

パーティションの更新範囲を分、時間、または日で指定します。Hologres は現在時刻から遡り、このウィンドウ内のパーティションを更新します。

アクティブパーティションとは、開始 (パーティション名から導出) からの経過時間が auto_refresh_partition_active_time の値より短いパーティションです。

説明
  • auto_refresh_partition_active_time パラメーターは、1 つのパーティション間隔より長い期間を指定する必要があります。例えば、データが日次でパーティション化されている場合、auto_refresh_partition_active_time は 24 時間より長い期間に設定する必要があります。

  • このパラメーターは変更可能です。変更は将来のパーティションにのみ影響します。

  • Hologres V4.2 から、動的テーブルのアクティブパーティションの更新は、テーブルレベルロックの代わりにパーティションレベルロックを使用します。これにより、異なるパーティションが互いに待つことなく同時に更新できます。

はい

デフォルトは パーティション間隔 + 1 時間 です。

これにより、ベーステーブルからの潜在的なデータ遅延を考慮するための 1 時間のバッファーが提供されます。例えば、日次パーティションの場合、デフォルトは 25 時間 (1 日 + 1 時間) になります。

partition_key_time_format

パーティション名のフォーマット。有効な値:

  • TEXT/VARCHAR パーティションキーの場合:

    YYYYMMDDHH24, YYYY-MM-DD-HH24, YYYY-MM-DD_HH24, YYYYMMDD, YYYY-MM-DD, YYYYMM, YYYY-MM, YYYY。

  • INT パーティションキーの場合:

    YYYYMMDDHH24, YYYYMMDD, YYYYMM, YYYY。

  • DATE パーティションキーの場合:

    YYYY-MM-DD

はい

なし

物理パーティションテーブル

パラメーター

説明

必須

デフォルト

PARTITION BY LIST(<partition_key>)

物理パーティション化された動的テーブルを作成します。

物理パーティション化された動的テーブルには動的パーティションがなく、使用制限があります。論理パーティションが推奨されます。違いについては、「CREATE LOGICAL PARTITION TABLE」をご参照ください。

重要

Hologres V3.1 以降では、動的テーブルを物理パーティションテーブルとして作成することはサポートされていません。

いいえ

なし

テーブルプロパティ

パラメーター

説明

必須

デフォルト値

完全更新モード

増分更新モード

col_name

列名。

名前のみを指定し、属性やデータ型は指定しないでください。エンジンがそれらを推論します。

説明

列の属性とデータ型を指定すると、エンジンの推論が不正確になる可能性があります。

いいえ

クエリ列名

クエリ列名

orientation

ストレージ形式。column は列指向ストレージを示します。

いいえ

column

column

table_group

テーブルグループ。デフォルトは現在のデータベースのデフォルトです。詳細については、「テーブルグループとシャードの管理」をご参照ください。

いいえ

デフォルトのテーブルグループ名

デフォルトのテーブルグループ名

distribution_key

ディストリビューションキー。詳細については、「ディストリビューションキー」をご参照ください。

いいえ

(なし)

(なし)

clustering_key

クラスタリングキー。詳細については、「クラスタリングキー」をご参照ください。

いいえ

許可されますが、デフォルトの推論値が使用されます。

許可されますが、デフォルトの推論値が使用されます。

event_time_column

「イベント時間列 (セグメントキー)」をご参照ください。

いいえ

(なし)

(なし)

bitmap_columns

ビットマップ列。詳細については、「ビットマップインデックス」をご参照ください。

いいえ

TEXT 型のフィールド

TEXT 型のフィールド

dictionary_encoding_columns

「辞書エンコーディング」をご参照ください。

いいえ

TEXT 型のフィールド

TEXT 型のフィールド

time_to_live_in_seconds

データ TTL。

いいえ

有効期限なし

有効期限なし

storage_mode

ストレージ階層。有効な値:

  • hot:ホットストレージ。

  • cold:コールドストレージ。

説明

詳細については、「ストレージ階層化の設定」をご参照ください。

いいえ

hot

hot

binlog_level

動的テーブルの binlog を有効にします。「Hologres Binlog のサブスクライブ」をご参照ください。

説明
  • このパラメーターには V3.1.18 以降が必要です。

  • 完全更新を使用する動的テーブルに対して binlog を有効にしないでください。

いいえ

none

none

binlog_ttl

binlog の TTL。

いいえ

2592000

2592000

カスケード更新

Hologres V5.0 以降では、カスケード更新がサポートされています。動的テーブルのベーステーブルに他の動的テーブルが含まれる場合、その freshness を 'upstream' に設定することで、上流の動的テーブルの更新が完了した後にテーブルが自動的に更新され、カスケード更新チェーンが形成されます。これは多層ウェアハウスのシナリオに適しています:チェーンのルートにのみ明示的な新鮮さの値を設定し、下流の各レイヤーを 'upstream' に設定します。これにより、各レイヤーに更新間隔を設定したり、依存関係を調整するための外部スケジューラを使用したりすることなく、データがレイヤーごとに流れます。

例
-- ルート:固定の新鮮さで更新されます。
CREATE DYNAMIC TABLE dwd_orders
WITH (
  auto_refresh_mode = 'incremental',
  freshness = '5 minutes'
)
AS SELECT order_id, user_id, ds, amount FROM ods_orders;

-- 第 2 レイヤー:dwd_orders が更新された後にトリガーされます。
CREATE DYNAMIC TABLE dws_user_amount
WITH (
  auto_refresh_mode = 'incremental',
  freshness = 'upstream'
)
AS SELECT user_id, ds, SUM(amount) AS amt FROM dwd_orders GROUP BY user_id, ds;

-- 第 3 レイヤー:dws_user_amount が更新された後にトリガーされます。
CREATE DYNAMIC TABLE ads_daily_amount
WITH (
  auto_refresh_mode = 'incremental',
  freshness = 'upstream'
)
AS SELECT ds, SUM(amt) AS amt FROM dws_user_amount GROUP BY ds;

カスケードチェーンを監視するには、hologres.hg_dynamic_table_refresh_history をクエリします。上流のテーブルによってトリガーされた更新は、トリガータイプ cascade で記録されます。

SELECT dynamic_table_name, refresh_type, status, refresh_start
FROM hologres.hg_dynamic_table_refresh_history
WHERE schema_name = '<SCHEMA_NAME>'
ORDER BY refresh_start;
トリガーの動作
  • トリガーは一度に 1 レベルずつ伝播します:上流の動的テーブルの更新が完了すると、その直接の下流テーブルがトリガーされ、それぞれが完了すると次のレベルをトリガーします。上流のテーブルが孫を直接トリガーすることはありません。A から B から C のチェーンでは、C は A ではなく B によってトリガーされます。

  • 上流のテーブルは、自身の更新が完了するとすぐに戻り、下流の更新を待ちません。これは手動の REFRESH DYNAMIC TABLE にも当てはまります:ステートメントは現在のテーブルが更新されると戻り、下流の更新はその後非同期で実行されます。手動更新が下流テーブルをトリガーするかどうかを制御するには、cascading パラメーターを使用します。詳細については、「動的テーブルの更新」をご参照ください。

  • 動的テーブルに複数の上流の動的テーブルがある場合、いずれかの上流テーブルの更新が成功すると、他の上流テーブルを待たずにこのテーブルの更新が 1 回トリガーされます。その結果、テーブルは一部の上流テーブルからの最新データと他のテーブルからの古いデータを組み合わせる可能性があります。これはカスケード更新の想定される動作です。ビジネス上、すべての上流データが整合している必要がある場合は、カスケードトリガーに依存しないでください。すべての上流データが準備できた後で、テーブルを手動で更新してください。

クエリ

動的テーブルのデータを定義するクエリ。サポートされるクエリとベーステーブルは更新モードによって異なります。詳細については、「動的テーブルのサポートと制限事項」をご参照ください。

V3.0 (レガシ構文)

動的テーブル作成の構文

CREATE DYNAMIC TABLE [IF NOT EXISTS] <schema.tablename>(
[col_name],
[col_name]
  ) [PARTITION BY LIST (col_name)]
WITH (
    [refresh_mode='[full|incremental]',]
    [auto_refresh_enable='[true|false',]

  --増分更新パラメーター:
    [incremental_auto_refresh_schd_start_time='[immediate|<timestamptz>]',]
    [incremental_auto_refresh_interval='[<num> {minute|minutes|hour|hours]',]  
    [incremental_guc_hg_computing_resource='[ local | serverless]',]
    [incremental_guc_hg_experimental_serverless_computing_required_cores='<num>',]

   --完全更新パラメーター:
    [full_auto_refresh_schd_start_time='[immediate|<timestamptz>]',]
    [full_auto_refresh_interval='[<num> {minute|minutes|hour|hours]',] 
    [full_guc_hg_computing_resource='[ local | serverless]',]--hg_full_refresh_computing_resource はデフォルトで serverless で、DB レベルで設定でき、ユーザーにとってはオプションです。
    [full_guc_hg_experimental_serverless_computing_required_cores='<num>',]
    
   --共有パラメーター、GUC が許可されます:
   [refresh_guc_<guc>='xxx]',] 
   
  -- 一般的な動的テーブルのプロパティ:
    [orientation = '[column]',]
    [table_group = '[tableGroupName]',]
    [distribution_key = 'columnName[,...]]',]
    [clustering_key = '[columnName{:asc]} [,...]]',]
    [event_time_column = '[columnName [,...]]',]
    [bitmap_columns = '[columnName [,...]]',]
    [dictionary_encoding_columns = '[columnName [,...]]',]
    [time_to_live_in_seconds = '<non_negative_literal>',]
    [storage_mode = '[hot | cold]']
    ) 
AS
<query> --クエリ定義

パラメーター

更新モードとリソース

カテゴリ

パラメーター

説明

必須

デフォルト

共有更新パラメーター

refresh_mode

更新モード。有効な値:full および incremental。

設定されていない場合、更新は実行されません。

いいえ

(なし)

auto_refresh_enable

自動更新を有効または無効にします。有効な値:

  • true

  • false

いいえ

false

refresh_guc_<guc>

更新用の GUC パラメーターを設定します。サポートされている GUC のリストについては、「GUC パラメーター」をご参照ください。

説明

例えば、タイムゾーン GUC を設定するには、refresh_guc_timezone = 'GMT-8:00' を使用します。

いいえ

(なし)

増分更新

incremental_auto_refresh_schd_start_time

増分更新の開始時刻。有効な値:

  • immediate:デフォルト。テーブル作成後すぐに増分更新を開始します。

  • <timestamptz>:カスタムの開始時刻。例えば、'2024-08-24 1:00' のように指定して、その時刻に更新タスクを開始します。

いいえ

immediate

incremental_auto_refresh_interval

増分更新の間隔 (分または時間)。

  • 値の範囲:[1分, 48時間]。

  • 設定されていない場合、動的テーブルは開始時刻に 1 回だけ更新されます。

いいえ

(なし)

incremental_guc_hg_computing_resource

増分更新のためのコンピューティングリソース。有効な値:

  • local:インスタンス自身のリソースを使用します。

  • serverless:サーバーレスコンピューティングリソースを使用します。インスタンスがサーバーレスコンピューティングの要件を満たしているか確認するには、「サーバーレスコンピューティングの利用」をご参照ください。

説明

DB レベルでコンピューティングリソースを設定するには、ALTER DATABASE xxx SET incremental_guc_hg_computing_resource=xx を実行します。

いいえ

local

incremental_guc_hg_experimental_serverless_computing_required_cores

更新用のサーバーレスコンピューティングコア。

説明

サーバーレスコンピューティングのリソースクォータはインスタンスの仕様によって異なります。詳細については、「サーバーレスコンピューティングリソースの管理」をご参照ください。

いいえ

(なし)

完全更新

full_auto_refresh_schd_start_time

完全更新の開始時刻。有効な値:

  • immediate:デフォルト。テーブル作成後すぐに完全更新を開始します。

  • <timestamptz>:カスタムの開始時刻。例えば、'2024-08-24 1:00' のように指定して、その時刻に更新タスクを開始します。

いいえ

immediate

full_auto_refresh_interval

完全更新の間隔 (分または時間)。

  • 値の範囲:[1分, 48時間]。

  • 設定されていない場合、動的テーブルは開始時刻に 1 回だけ更新されます。

いいえ

(なし)

full_guc_hg_computing_resource

完全更新のためのコンピューティングリソース。有効な値:

  • local:インスタンス自身のリソース。

  • serverless:サーバーレスコンピューティングリソースを使用します。インスタンスがサーバーレスコンピューティングの要件を満たしているか確認するには、「サーバーレスコンピューティングの利用」をご参照ください。

説明

DB レベルでコンピューティングリソースを設定するには、ALTER DATABASE xxx SET full_guc_hg_computing_resource=xx を実行します。

いいえ

local

full_guc_hg_experimental_serverless_computing_required_cores

更新用のサーバーレスコンピューティングコア。

説明

サーバーレスコンピューティングのリソースクォータはインスタンスの仕様によって異なります。詳細については、「サーバーレスコンピューティングリソースの管理」をご参照ください。

いいえ

(なし)

テーブルプロパティ

パラメーター

説明

必須

デフォルト

full

incremental

col_name

列名。

名前のみを指定し、属性やデータ型は指定しないでください。エンジンがそれらを推論します。

説明

列の属性とデータ型を指定すると、エンジンの推論が不正確になる可能性があります。

いいえ

クエリ列名

クエリ列名

orientation

動的テーブルのストレージ形式。column は列指向ストレージを示します。

いいえ

column

column

table_group

テーブルグループ。デフォルトは現在のデータベースのデフォルトです。詳細については、「テーブルグループとシャードの管理」をご参照ください。

いいえ

デフォルトのテーブルグループ名

デフォルトのテーブルグループ名

distribution_key

ディストリビューションキー。詳細については、「ディストリビューションキー」をご参照ください。

いいえ

(なし)

(なし)

clustering_key

クラスタリングキー。詳細については、「クラスタリングキー」をご参照ください。

いいえ

許可されますが、デフォルトの推論値が使用されます。

許可されますが、デフォルトの推論値が使用されます。

event_time_column

セグメントキー。詳細については、「イベント時間列 (セグメントキー)」をご参照ください。

いいえ

(なし)

(なし)

bitmap_columns

ビットマップ列。詳細については、「ビットマップインデックス」をご参照ください。

いいえ

TEXT 型のフィールド

TEXT 型のフィールド

dictionary_encoding_columns

「辞書エンコーディング」をご参照ください。

いいえ

TEXT 型のフィールド

TEXT 型のフィールド

time_to_live_in_seconds

データ TTL。

いいえ

有効期限なし

有効期限なし

storage_mode

ストレージ階層。有効な値:

  • hot:ホットストレージ。

  • cold:コールドストレージ。

説明

「ストレージ階層化の設定」をご参照ください。

いいえ

hot

hot

PARTITION BY LIST

パーティション化された動的テーブルを作成します。パーティションは、異なる新鮮さのニーズに合わせて異なる更新モードを使用できます。

いいえ

非パーティションテーブル

非パーティションテーブル

クエリ

動的テーブルのデータを生成するクエリ。サポートされるクエリとベーステーブルのタイプは更新モードによって異なります。「動的テーブルのサポートと制限事項」をご参照ください。

増分更新

増分更新は、ベーステーブルの変更を検出し、差分のみを動的テーブルに書き込みます。ニアリアルタイム (分単位) のクエリに最適です。

  • ベーステーブルの制限:

    • V3.1 はデフォルトで stream モードになります。V3.0 でベーステーブルに binlog が有効になっていた場合は、追加のストレージコストを避けるために無効にしてください。

    • V3.0 では、JOIN に関連するディメンションテーブルを除き、ベーステーブルに対して binlog を有効にする必要があります。ベーステーブルに対して binlog を有効にすると、ある程度のストレージオーバーヘッドが発生します。binlog のストレージ使用量を確認するには、「テーブルのストレージ詳細の表示」をご参照ください。

  • 増分更新モードでは、Hologres はバックグラウンドで状態テーブルを生成し、中間集計結果を記録します (詳細は「動的テーブル」をご参照ください)。状態テーブルも状態ストレージのためにいくらかのスペースを消費します。ストレージ使用量を確認するには、「動的テーブルのスキーマとリネージの表示」をご参照ください。

  • 増分更新でサポートされるクエリと演算子:「動的テーブルのサポートと制限事項」。

  • 増分更新を初めて実行すると、システムは完全なデータロードを実行し、状態追跡に使用される状態テーブルを初期化します。すべての既存データを一度に処理し、状態構造を初期化する必要があるため、メモリとコンピューティングリソースの消費は、後続の増分サイクルよりも大幅に高くなります。ベーステーブルのデータ量が大きい場合やリソースが不足している場合、メモリ不足 (OOM) エラーが発生する可能性があります。

  • リソースのボトルネックを避けるために、初回実行前にベーステーブルのデータ量を評価し、サーバーレスコンピューティングリソースを使用して最初の更新を実行してください。詳細については、「データの読み書きにサーバーレスコンピューティングを使用する」をご参照ください。

ストリーム-ストリーム JOIN

ストリーム-ストリーム JOIN は OLAP クエリと同じセマンティクスを持ち、HASH JOIN を使用し、INNER JOIN、LEFT/RIGHT/FULL OUTER JOIN をサポートします。

V3.1

説明

Hologres V3.1 から、ストリーム-ストリーム JOIN の GUC はデフォルトで有効になっています。

例:

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
);
INSERT INTO orders VALUES(1, 1);

CREATE DYNAMIC TABLE dt WITH (
  auto_refresh_mode = 'incremental',
  freshness='10 minutes'
) 
AS 
SELECT order_id, orders.user_id, user_name 
FROM orders LEFT JOIN users ON orders.user_id = users.user_id;

-- 更新後、結合された 1 つのレコードが表示されます
REFRESH TABLE dt;
SELECT * FROM dt;
 order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)


UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- 更新後、結合された 2 つのレコードが表示されます。ディメンションテーブルの更新はすべてのデータに影響し、以前に結合されたレコードを修正できます。
REFRESH TABLE dt;
SELECT * FROM dt;

結果:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | dynamic table
        4 |       1 | dynamic table
(2 rows)

V3.0

ストリーム-ストリーム JOIN は V3.0.26 でサポートされています。この機能を有効にするには、インスタンスをアップグレードし、GUC を有効にしてください:

-- セッションレベルで有効にする
SET hg_experimental_incremental_dynamic_table_enable_hash_join TO ON;

-- DB レベルで有効にする (新しい接続に対して有効)
ALTER database <db_name> SET hg_experimental_incremental_dynamic_table_enable_hash_join TO ON;

例:

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
) WITH (binlog_level = 'replica');
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
)  WITH (binlog_level = 'replica');
INSERT INTO orders VALUES(1, 1);

CREATE DYNAMIC TABLE dt WITH (refresh_mode = 'incremental') 
AS 
SELECT order_id, orders.user_id, user_name 
FROM orders LEFT JOIN users ON orders.user_id = users.user_id;

-- 更新後、結合された 1 つのレコードが表示されます
REFRESH TABLE dt;
SELECT * FROM dt;
 order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)


UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- 更新後、結合された 2 つのレコードが表示されます。ディメンションテーブルの更新はすべてのデータに影響し、以前に結合されたレコードを修正できます。
REFRESH TABLE dt;
SELECT * FROM dt;

結果:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | dynamic table
        4 |       1 | dynamic table
(2 rows)

ディメンションテーブルの JOIN

各ストリームレコードは、処理時間におけるディメンションテーブルの最新のスナップショットと結合します。JOIN 後にディメンションテーブルが変更されても、すでに処理されたデータには影響しません。

説明

ディメンションテーブルの JOIN の動作はテーブルサイズに依存せず、JOIN ステートメントによって決定されます。

V3.1

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
)  WITH (binlog_level = 'replica');

INSERT INTO orders VALUES(1, 1);
CREATE DYNAMIC TABLE dt_join_2 WITH (
    auto_refresh_mode = 'incremental',
    freshness='10 minutes') 
AS 
SELECT order_id, orders.user_id, user_name 
-- FOR SYSTEM_TIME AS OF PROCTIME() は 'users' をディメンションテーブルとして識別します
FROM orders LEFT JOIN users FOR SYSTEM_TIME AS OF PROCTIME()
ON orders.user_id = users.user_id;

-- 更新後、結合された 1 つのレコードが表示されます
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;
 order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)


UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- 更新後、結合された 2 つのレコードが表示されます。ディメンションテーブルの更新は新しいデータにのみ影響し、以前に結合されたデータを修正することはできません。
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;

結果:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | hologres
        4 |       1 | dynamic table
(2 rows)

V3.0

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
)  WITH (binlog_level = 'replica');
INSERT INTO orders VALUES(1, 1);

CREATE DYNAMIC TABLE dt_join_2 WITH (refresh_mode = 'incremental') 
AS 
SELECT order_id, orders.user_id, user_name 
-- FOR SYSTEM_TIME AS OF PROCTIME() は 'users' をディメンションテーブルとして識別します
FROM orders LEFT JOIN users FOR SYSTEM_TIME AS OF PROCTIME()
ON orders.user_id = users.user_id;

-- 更新後、結合された 1 つのレコードが表示されます
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;

order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)
 
UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- 更新後、結合された 2 つのレコードが表示されます。ディメンションテーブルの更新は新しいデータにのみ影響し、以前に結合されたデータを修正することはできません。
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;

結果:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | hologres
        4 |       1 | dynamic table
(2 rows)

制限事項

ディメンションテーブルの JOIN から取得された列は非決定的です:その値は現在のファクトテーブルの行と処理時間におけるディメンションテーブルの内容の両方に依存します。この点で、非決定的な関数 NOW() や RAND() のように動作します。このような列は SELECT プロジェクションリストでのみ使用することを推奨します。他の場所で使用すると、更新エラーや予期しない結果を引き起こす可能性があります。

使用場所

許可

SELECT プロジェクションリスト

はい

集計関数の引数、例:SUM(p.price)

はい、ただし非推奨です。リトラクションが再計算をトリガーした際に、ディメンションテーブルの値がすでに変更されている可能性があり、予期しない結果を生むことがあります。

GROUP BY キー

いいえ

WHERE 述語

いいえ

下流の JOIN の ON 条件

いいえ

ウィンドウ関数の PARTITION BY 句

いいえ

ビジネスロジックでディメンションテーブルの列によるグループ化やフィルタリングが必要な場合は、代わりにストリーム-ストリーム JOIN を使用してください。これにより、ディメンションテーブルの変更がリトラクションと既存データの再計算をトリガーし、結果の正確性を保ちます。

ただし、ストリーム-ストリーム JOIN は JOIN 状態を維持する必要があるため、ディメンションテーブルが大きい場合にはより多くのリソースを消費します。また、ディメンションテーブルへの一括変更は、広範囲な下流の再計算をトリガーする可能性があります。

Paimon レイクテーブルの増分消費

  • 増分更新は、レイクハウスシナリオ向けに Paimon テーブルの消費をサポートします。

  • 外部動的テーブルは増分読み取りと書き戻しをサポートし、処理コストとクエリのレイテンシを削減します。「外部動的テーブルの紹介」をご参照ください。

ハイブリッド消費

増分動的テーブルはハイブリッドモデルをサポートします:既存のベーステーブルデータの初期完全ロードに続き、継続的な増分処理を行います。

V3.1

V3.1 では、ハイブリッド更新モデルがデフォルトで有効になっています。例:

--ベーステーブルを準備し、データを挿入します
CREATE TABLE base_sales(
  day TEXT NOT NULL,
  hour INT,
  user_id BIGINT,
  ts TIMESTAMPTZ,
  amount FLOAT,
  pk text NOT NULL PRIMARY KEY
);

-- ベーステーブルにデータをインポートします
INSERT INTO base_sales values ('2024-08-29',1,222222,'2024-08-29 16:41:19.141528+08',5,'ddd');


-- さらにデータをインポートします
INSERT INTO base_sales VALUES ('2024-08-29',2,3333,'2024-08-29 17:44:19.141528+08',100,'aaaaa');


-- 増分動的テーブルを作成します
CREATE DYNAMIC TABLE sales_incremental
  WITH (
    auto_refresh_mode='incremental',
    freshness='10 minutes'
  ) 
AS 
  SELECT day, hour, SUM(amount), COUNT(1) 
    FROM base_sales 
  GROUP BY day, hour;

データ整合性の確認:

  • ベーステーブルをクエリします

    SELECT day, hour, SUM(amount), COUNT(1) 
        FROM base_sales 
      GROUP BY day, hour;

    結果:

    day	    hour	sum	count
    2024-08-29	2	100	1
    2024-08-29	1	5	1
  • 動的テーブルをクエリします

    SELECT * FROM sales_incremental;

    結果:

    day	    hour	sum	count
    2024-08-29	1	5	1
    2024-08-29	2	100	1

V3.0

V3.0 でハイブリッド消費を使用するには、手動で GUC incremental_guc_hg_experimental_enable_hybrid_incremental_mode を有効にする必要があります。例:

--ベーステーブルを準備し、Binlog を有効にしてデータを挿入します
CREATE TABLE base_sales(
  day TEXT NOT NULL,
  hour INT,
  user_id BIGINT,
  ts TIMESTAMPTZ,
  amount FLOAT,
  pk text NOT NULL PRIMARY KEY
);

-- ベーステーブルにデータをインポートします
INSERT INTO base_sales values ('2024-08-29',1,222222,'2024-08-29 16:41:19.141528+08',5,'ddd');

-- ベーステーブルの Binlog を有効にします
ALTER TABLE base_sales SET (binlog_level = replica);

-- ベーステーブルに増分データをインポートします
INSERT INTO base_sales VALUES ('2024-08-29',2,3333,'2024-08-29 17:44:19.141528+08',100,'aaaaa');


-- 自動更新の増分動的テーブルを作成し、ハイブリッド消費のための GUC を有効にします
CREATE DYNAMIC TABLE sales_incremental
  WITH (
    refresh_mode='incremental',
    incremental_auto_refresh_schd_start_time = 'immediate',
    incremental_auto_refresh_interval = '3 minutes',
    incremental_guc_hg_experimental_enable_hybrid_incremental_mode= 'true'
  ) 
AS 
  SELECT day, hour, SUM(amount), COUNT(1) 
    FROM base_sales 
  GROUP BY day, hour;

データ整合性の確認:

  • ベーステーブルをクエリします

    SELECT day, hour, SUM(amount), COUNT(1) 
        FROM base_sales 
      GROUP BY day, hour;

    結果:

    day	    hour	sum	count
    2024-08-29	2	100	1
    2024-08-29	1	5	1
  • 動的テーブルをクエリします

    SELECT * FROM sales_incremental;

    結果:

    day	    hour	sum	count
    2024-08-29	1	5	1
    2024-08-29	2	100	1

完全更新

完全更新は、クエリからデータセット全体を再書き込みします。増分更新と比較して:

  • より多くのベーステーブルタイプをサポートします。

  • より豊富なクエリタイプと演算子をサポートします。

完全更新はより多くのリソースを使用します。定期的なレポート作成やデータバックフィルに最適です。

説明

詳細については、「完全更新」をご参照ください。

例

V3.1

例 1:通常の増分動的テーブルの作成

進む前に、「数回のクリックでパブリックデータセットをインポート」のガイドに従って、tpch_10g パブリックデータセットを Hologres にインポートしてください。

説明

増分動的テーブルを作成する前に、ベーステーブルの Binlog を有効にしてください (ディメンションテーブルには不要です)。

-- 3 分ごとに更新する増分動的テーブルを作成します。
CREATE DYNAMIC TABLE public.tpch_q1_incremental 
WITH (
auto_refresh_mode='incremental',
freshness='3 minutes'
) AS SELECT
        l_returnflag,
        l_linestatus,
        COUNT(*) AS count_order
FROM
        hologres_dataset_tpch_10g.lineitem
WHERE
        l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
        l_returnflag,
        l_linestatus;

例 2:ストリーム-ストリーム JOIN から増分動的テーブルを作成する

進む前に、「数回のクリックでパブリックデータセットをインポート」のガイドに従って、tpch_10g パブリックデータセットを Hologres にインポートしてください。

説明

増分動的テーブルを作成する前に、ベーステーブルの binlog を有効にしてください (ディメンションテーブルには不要です)。

-- ストリーム-ストリーム JOIN から増分動的テーブルを作成します。
CREATE DYNAMIC TABLE dt_join
  WITH (
    auto_refresh_mode='incremental',
    freshness='30 minutes'
  ) 
AS 
SELECT
        l_shipmode,
        SUM(CASE
                WHEN o_orderpriority = '1-URGENT'
                        OR o_orderpriority = '2-HIGH'
                        THEN 1
                ELSE 0
        END) AS high_line_count,
        SUM(CASE
                WHEN o_orderpriority <> '1-URGENT'
                        AND o_orderpriority <> '2-HIGH'
                        THEN 1
                ELSE 0
        END) AS low_line_count
FROM
        hologres_dataset_tpch_10g.orders,
        hologres_dataset_tpch_10g.lineitem
WHERE
        o_orderkey = l_orderkey
        AND l_shipmode IN ('FOB', 'AIR')
        AND l_commitdate < l_receiptdate
        AND l_shipdate < l_commitdate
        AND l_receiptdate >= DATE '1997-01-01'
        AND l_receiptdate < DATE '1997-01-01' + INTERVAL '1' YEAR
GROUP BY
        l_shipmode;

例 3:自動更新動的テーブルの作成

更新モードを auto に設定します。エンジンは増分更新を優先し、サポートされていない場合は完全更新にフォールバックします。

進む前に、「数回のクリックでパブリックデータセットをインポート」のガイドに従って、tpch_10g パブリックデータセットを Hologres にインポートしてください。

-- 更新モードをインテリジェントに決定する自動更新動的テーブルを作成します。この例では、増分更新が結果となります。
CREATE DYNAMIC TABLE thch_q6_auto
  WITH (
    auto_refresh_mode='auto',
    freshness='1 hours'
       ) 
AS
SELECT
        SUM(l_extendedprice * l_discount) AS revenue
FROM
        hologres_dataset_tpch_100g.lineitem
WHERE
        l_shipdate >= DATE '1996-01-01'
        AND l_shipdate < DATE '1996-01-01' + INTERVAL '1' YEAR
        AND l_discount BETWEEN 0.02 - 0.01 AND 0.02 + 0.01
        AND l_quantity < 24;

例 4:論理パーティション動的テーブルの作成

リアルタイムのトランザクションダッシュボードでは、現在のデータのニアリアルタイム表示と既存データの修正の両方が必要になることが多く、統合されたリアルタイムおよびオフライン分析ソリューションが必要です (ビジネスとデータの認識)。通常、このシナリオでは `動的テーブル` の論理パーティションを使用します。アプローチは次のとおりです:

  • ベーステーブルは日次でパーティション化されます。最新のパーティションは Flink によってリアルタイム/ニアリアルタイムで書き込まれ、既存のパーティションは MaxCompute から書き込まれます。

  • 動的テーブルは論理パーティションテーブルとして作成されます。最新の 2 つのパーティションはアクティブであり、ニアリアルタイムのデータ分析のために増分更新されます。

  • 既存のパーティションは非アクティブで、完全更新を使用します。ベーステーブルの既存のパーティションが修正またはバックフィルされた場合、完全更新を使用して更新できます。

この例では、GitHub のパブリックデータセットを使用します。

  1. ベーステーブルを準備します。

    Flink を使用して最新のデータをベーステーブルに書き込みます。詳細な手順については、「GitHub イベントのバッチおよびリアルタイム分析の統合」をご参照ください。

    DROP TABLE IF EXISTS gh_realtime_data;
    
    BEGIN;
    CREATE TABLE gh_realtime_data (
        id BIGINT,
        actor_id BIGINT,
        actor_login TEXT,
        repo_id BIGINT,
        repo_name TEXT,
        org_id BIGINT,
        org_login TEXT,
        type TEXT,
        created_at timestamp with time zone NOT NULL,
        action TEXT,
        iss_or_pr_id BIGINT,
        number BIGINT,
        comment_id BIGINT,
        commit_id TEXT,
        member_id BIGINT,
        rev_or_push_or_rel_id BIGINT,
        ref TEXT,
        ref_type TEXT,
        state TEXT,
        author_association TEXT,
        language TEXT,
        merged BOOLEAN,
        merged_at TIMESTAMP WITH TIME ZONE,
        additions BIGINT,
        deletions BIGINT,
        changed_files BIGINT,
        push_size BIGINT,
        push_distinct_size BIGINT,
        hr TEXT,
        month TEXT,
        year TEXT,
        ds TEXT,
        PRIMARY KEY (id,ds)
    )
    PARTITION BY LIST (ds);
    CALL set_table_property('public.gh_realtime_data', 'distribution_key', 'id');
    CALL set_table_property('public.gh_realtime_data', 'event_time_column', 'created_at');
    CALL set_table_property('public.gh_realtime_data', 'clustering_key', 'created_at');
    
    COMMENT ON COLUMN public.gh_realtime_data.id IS 'イベント ID';
    COMMENT ON COLUMN public.gh_realtime_data.actor_id IS 'イベントアクター ID';
    COMMENT ON COLUMN public.gh_realtime_data.actor_login IS 'イベントアクターログイン名';
    COMMENT ON COLUMN public.gh_realtime_data.repo_id IS 'リポジトリ ID';
    COMMENT ON COLUMN public.gh_realtime_data.repo_name IS 'リポジトリ名';
    COMMENT ON COLUMN public.gh_realtime_data.org_id IS 'リポジトリ組織 ID';
    COMMENT ON COLUMN public.gh_realtime_data.org_login IS 'リポジトリ組織名';
    COMMENT ON COLUMN public.gh_realtime_data.type IS 'イベントタイプ';
    COMMENT ON COLUMN public.gh_realtime_data.created_at IS 'イベント時間';
    COMMENT ON COLUMN public.gh_realtime_data.action IS 'イベントアクション';
    COMMENT ON COLUMN public.gh_realtime_data.iss_or_pr_id IS 'Issue/pull_request ID';
    COMMENT ON COLUMN public.gh_realtime_data.number IS 'Issue/pull_request 番号';
    COMMENT ON COLUMN public.gh_realtime_data.comment_id IS 'コメント ID';
    COMMENT ON COLUMN public.gh_realtime_data.commit_id IS 'コミット ID';
    COMMENT ON COLUMN public.gh_realtime_data.member_id IS 'メンバー ID';
    COMMENT ON COLUMN public.gh_realtime_data.rev_or_push_or_rel_id IS 'レビュー/プッシュ/リリース ID';
    COMMENT ON COLUMN public.gh_realtime_data.ref IS '作成/削除されたリソースの名前';
    COMMENT ON COLUMN public.gh_realtime_data.ref_type IS '作成/削除されたリソースのタイプ';
    COMMENT ON COLUMN public.gh_realtime_data.state IS 'Issue/pull_request/pull_request_review の状態';
    COMMENT ON COLUMN public.gh_realtime_data.author_association IS 'アクターとリポジトリの関係';
    COMMENT ON COLUMN public.gh_realtime_data.language IS 'プログラミング言語';
    COMMENT ON COLUMN public.gh_realtime_data.merged IS 'マージされたかどうか';
    COMMENT ON COLUMN public.gh_realtime_data.merged_at IS 'マージ時間';
    COMMENT ON COLUMN public.gh_realtime_data.additions IS '追加された行数';
    COMMENT ON COLUMN public.gh_realtime_data.deletions IS '削除された行数';
    COMMENT ON COLUMN public.gh_realtime_data.changed_files IS 'プルリクエストで変更されたファイル数';
    COMMENT ON COLUMN public.gh_realtime_data.push_size IS 'プッシュ数';
    COMMENT ON COLUMN public.gh_realtime_data.push_distinct_size IS '個別プッシュ数';
    COMMENT ON COLUMN public.gh_realtime_data.hr IS 'イベントの時間、例:00:23 の場合は 00';
    COMMENT ON COLUMN public.gh_realtime_data.month IS 'イベントの月、例:2015年10月の場合は 2015-10';
    COMMENT ON COLUMN public.gh_realtime_data.year IS 'イベントの年、例:2015';
    COMMENT ON COLUMN public.gh_realtime_data.ds IS 'イベントの日付、ds=yyyy-mm-dd';
    
    COMMIT;
  2. 論理パーティション動的テーブルを作成します。

    CREATE  DYNAMIC TABLE ads_dt_github_event
    LOGICAL PARTITION BY LIST(ds)
    WITH (
      -- 動的テーブルのプロパティ
      freshness = '5 minutes', 
      auto_refresh_mode = 'auto', 
      auto_refresh_partition_active_time = '2 days' ,
      partition_key_time_format = 'YYYY-MM-DD'
    )
    AS
    SELECT
        repo_name,
        COUNT(*) AS events,
        ds
    FROM
        gh_realtime_data
    GROUP BY repo_name,ds
  3. 動的テーブルをクエリします。

    SELECT * FROM ads_dt_github_event ;
  4. 既存のパーティションをバックフィルします。

    ベーステーブルの既存データが変更された場合 (例:'2025-04-01' のデータ)、動的テーブルを更新する必要がある場合は、既存のパーティションを完全更新モードに設定し、更新をトリガーします。サーバーレスコンピューティングリソースを使用することが望ましいです。

    REFRESH OVERWRITE DYNAMIC TABLE ads_dt_github_event
    PARTITION (ds = '2025-04-01') 
    WITH (
      refresh_mode = 'full'
    );

例 5:増分動的テーブルで UV を計算する

Hologres V3.1 から、増分動的テーブルは RB_BUILD_AGG 関数をサポートし、UV 数などの計算が可能です。事前集計と比較して、以下の利点があります:

  • より高速なパフォーマンス:増分データのみを計算します。

  • 低コスト:データ量とリソース使用量が削減され、より長期間にわたる計算が可能になります。

例:

  1. ユーザー詳細テーブルを準備します。

    BEGIN;
    CREATE TABLE IF NOT EXISTS ods_app_detail (
         uid INT,
         country TEXT,
         prov TEXT,
         city TEXT,
         channel TEXT,
         operator TEXT,
         brand TEXT,
         ip TEXT,
         click_time TEXT,
         year TEXT,
         month TEXT,
         day TEXT,
         ymd TEXT NOT NULL
    );
    CALL set_table_property('ods_app_detail', 'orientation', 'column');
    CALL set_table_property('ods_app_detail', 'bitmap_columns', 'country,prov,city,channel,operator,brand,ip,click_time, year, month, day, ymd');
    -- 最適なシャーディング効果を得るために、クエリのニーズに基づいて distribution_key を設定します。
    CALL set_table_property('ods_app_detail', 'distribution_key', 'uid');
    -- WHERE フィルターで使用される完全な日時を持つフィールドについては、clustering_key と event_time_column として設定することを推奨します。
    CALL set_table_property('ods_app_detail', 'clustering_key', 'ymd');
    CALL set_table_property('ods_app_detail', 'event_time_column', 'ymd');
    COMMIT;
  2. 増分動的テーブルを使用して UV を計算します。

    CREATE DYNAMIC TABLE ads_uv_dt
      WITH (
        freshness = '5 minutes', 
        auto_refresh_mode = 'incremental') 
      AS 
    SELECT  
     RB_BUILD_AGG(uid),
     country,
     prov,
     city,
     ymd,
    COUNT(1)
    FROM    ods_app_detail
    WHERE ymd >= '20231201' AND ymd <='20240502'
    GROUP BY country,prov,city,ymd;
  3. 特定の日付の UV をクエリします。

    SELECT  
    RB_CARDINALITY(RB_OR_AGG(rb_uid)) AS uv,
      country,
      prov,
      city,
      SUM(pv) AS pv
    FROM    ads_uv_dt
    WHERE   ymd = '20240329'
    GROUP BY country,prov,city;

V3.0

例 1:自動開始の完全更新動的テーブルの作成

進む前に、「数回のクリックでパブリックデータセットをインポート」のガイドに従って、tpch_10g パブリックデータセットを Hologres にインポートしてください。

--「test」スキーマを作成
CREATE SCHEMA test;

--単一テーブルの完全更新動的テーブルを作成し、即時開始して 1 時間ごとに更新します。
CREATE DYNAMIC TABLE test.thch_q1_full
  WITH (
    refresh_mode='full',
    auto_refresh_enable='true',
    full_auto_refresh_interval='1 hours',
    full_guc_hg_computing_resource='serverless',
    full_guc_hg_experimental_serverless_computing_required_cores='32'
       ) 
AS
  SELECT
        l_returnflag,
        l_linestatus,
        SUM(l_quantity) AS sum_qty,
        SUM(l_extendedprice) AS sum_base_price,
        SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
        SUM(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,
        AVG(l_quantity) AS avg_qty,
        AVG(l_extendedprice) AS avg_price,
        AVG(l_discount) AS avg_disc,
        COUNT(*) AS count_order
FROM
        hologres_dataset_tpch_10g.lineitem
WHERE
        l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
        l_returnflag,
        l_linestatus;

例 2:開始時刻を指定した増分動的テーブルの作成

進む前に、「数回のクリックでパブリックデータセットをインポート」のガイドに従って、tpch_10g パブリックデータセットを Hologres にインポートしてください。

例:

説明

増分 `動的テーブル` を作成する前に、ベーステーブルの Binlog を有効にする必要があります (ディメンションテーブルには不要です)。

--ベーステーブルの binlog を有効にする:
BEGIN;
CALL set_table_property('hologres_dataset_tpch_10g.lineitem', 'binlog.level', 'replica');
COMMIT;

--単一テーブルの増分更新動的テーブルを作成し、開始時刻と 3 分の更新間隔を指定します。
CREATE DYNAMIC TABLE public.tpch_q1_incremental 
WITH (
refresh_mode='incremental',
auto_refresh_enable='true',
incremental_auto_refresh_schd_start_time='2024-09-15 23:50:0',
incremental_auto_refresh_interval='3 minutes',
incremental_guc_hg_computing_resource='serverless',
incremental_guc_hg_experimental_serverless_computing_required_cores='30'
) AS SELECT
        l_returnflag,
        l_linestatus,
        COUNT(*) AS count_order
FROM
        hologres_dataset_tpch_10g.lineitem
WHERE
        l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
        l_returnflag,
        l_linestatus
;

例 3:複数 JOIN の完全更新動的テーブルの作成

--複数テーブル JOIN クエリを持つ動的テーブルを作成し、3 時間ごとに完全更新モードを使用します。
CREATE DYNAMIC TABLE dt_q_full
  WITH (
    refresh_mode='full',
    auto_refresh_enable='true',
    full_auto_refresh_schd_start_time='immediate',
    full_auto_refresh_interval='3 hours',
    full_guc_hg_computing_resource='serverless',
    full_guc_hg_experimental_serverless_computing_required_cores='64'
  ) 
AS 
SELECT
        o_orderpriority,
        COUNT(*) AS order_count
FROM
        hologres_dataset_tpch_10g.orders
WHERE
        o_orderdate >= DATE '1996-07-01'
        AND o_orderdate < DATE '1996-07-01' + INTERVAL '3' MONTH
        AND EXISTS (
                SELECT
                        *
                FROM
                        hologres_dataset_tpch_10g.lineitem
                WHERE
                        l_orderkey = o_orderkey
                        AND l_commitdate < l_receiptdate
        )
GROUP BY
        o_orderpriority;

例 4:ディメンション JOIN の増分動的テーブルの作成

例:

説明

増分 `動的テーブル` を作成する前に、ベーステーブルの Binlog を有効にする必要があります (ディメンションテーブルには不要です)。

ディメンションテーブル JOIN のセマンティクスは、各レコードがその時点でのディメンションテーブルデータの最新バージョンとのみ結合される、つまり JOIN が処理時に行われるということです。JOIN 後にディメンションテーブルのデータが変更 (追加、更新、または削除) されても、すでに結合されたデータは更新されません。SQL の例:

--詳細テーブル
BEGIN;
CREATE TABLE public.sale_detail(
        app_id TEXT,
        uid TEXT,
        product TEXT,
        gmv BIGINT,
        order_time TIMESTAMPTZ
);
--ベーステーブルの binlog を有効にします。ディメンションテーブルには不要です。
CALL set_table_property('public.sale_detail', 'binlog.level', 'replica');
COMMIT;

--プロパティテーブル
CREATE TABLE public.user_info(
        uid TEXT,
        province TEXT,
        city TEXT
);

CREATE DYNAMIC TABLE public.dt_sales_incremental
  WITH (
    refresh_mode='incremental',
    auto_refresh_enable='true',
    incremental_auto_refresh_schd_start_time='2024-09-15 00:00:00',
    incremental_auto_refresh_interval='5 minutes',
    incremental_guc_hg_computing_resource='serverless',
    incremental_guc_hg_experimental_serverless_computing_required_cores='128') 
AS 
SELECT 
    sale_detail.app_id,
    sale_detail.uid,
    product,
    SUM(sale_detail.gmv) AS sum_gmv,
    sale_detail.order_time,
    user_info.province,
    user_info.city 
FROM public.sale_detail 
INNER JOIN public.user_info  FOR SYSTEM_TIME AS OF PROCTIME()
ON sale_detail.uid =user_info.uid
GROUP BY sale_detail.app_id,sale_detail.uid,sale_detail.product,sale_detail.order_time,user_info.province,user_info.city;

例 5:パーティション動的テーブルの作成

リアルタイムのトランザクションダッシュボードでは、現在のデータのニアリアルタイム表示と既存データの修正の両方が必要になることがよくあります。これは、`動的テーブル` の増分更新と完全更新を組み合わせて実現できます。アプローチは次のとおりです:

  1. パーティション化されたベーステーブルを作成し、最新のパーティションはリアルタイム/ニアリアルタイムで書き込まれ、既存のパーティションは時々修正されます。

  2. `動的テーブル` をパーティション化された親テーブルとして作成します。最新のパーティションには増分更新を使用して、ニアリアルタイムの分析ニーズに対応します。

  3. 既存のパーティションを完全更新モードに切り替えます。ソーステーブルの既存のパーティションが修正された場合、`動的テーブル` のパーティションも完全更新を使用してバックフィルできます。高速化のためにサーバーレスを使用することが望ましいです。

例:

  1. ベーステーブルとデータを準備します。

    ベーステーブルはパーティションテーブルで、最新のパーティションがリアルタイムデータを受け取ります。

    -- パーティション化されたソーステーブルを作成
    CREATE TABLE base_sales(
      uid INT,
      opreate_time TIMESTAMPTZ,
      amount FLOAT,
      tt TEXT NOT NULL,
      ds TEXT,
      PRIMARY KEY(ds)
    ) PARTITION BY LIST (ds) ;
    
    --既存のパーティション
    CREATE TABLE base_sales_20240615 PARTITION OF base_sales FOR VALUES IN ('20240615');
    INSERT INTO base_sales_20240615 VALUES (2,'2024-06-15 16:18:25.387466+08','111','2','20240615');
    
    --最新のパーティション、通常はリアルタイム書き込み用
    CREATE TABLE base_sales_20240616 PARTITION OF base_sales FOR VALUES IN ('20240616');
    INSERT INTO base_sales_20240616 VALUES (1,'2024-06-16 16:08:25.387466+08','2','1','20240616');

  2. パーティション化された `動的テーブル` の親テーブルを作成し、更新モードなしでクエリのみを定義します。

    --拡張機能を作成
    CREATE EXTENSION roaringbitmap;
    
    CREATE DYNAMIC TABLE partition_dt_base_sales
    PARTITION BY LIST (ds)
    as
    SELECT  
     public.RB_BUILD_AGG(uid),
     opreate_time,
     amount,
     tt,
     ds,
    COUNT(1)
    FROM    base_sales
    GROUP BY opreate_time ,amount,tt,ds;

  3. サブテーブルを作成し、その更新モードを設定します。

    `動的テーブル` のサブパーティションは手動で作成するか、DataWorks を使用して動的に作成できます。最新のパーティションを増分更新に設定し、既存のパーティションを完全更新に設定します。

    -- ベーステーブルの Binlog を有効にする
    ALTER TABLE base_sales SET (binlog_level = replica);
    
    -- 既存の動的テーブルのサブパーティションは次のようになると仮定します:
    CREATE DYNAMIC TABLE partition_dt_base_sales_20240615 PARTITION OF partition_dt_base_sales FOR VALUES IN ('20240615')
      WITH (
        refresh_mode='incremental',
        auto_refresh_enable='true',
        incremental_auto_refresh_schd_start_time='immediate',
        incremental_auto_refresh_interval='30 minutes'
           );
    
    -- 新しい動的テーブルのサブパーティションを作成し、その更新モードを増分に設定し、即時開始し、30 分ごとに更新し、インスタンスリソースを使用します。
    CREATE DYNAMIC TABLE partition_dt_base_sales_20240616 PARTITION OF partition_dt_base_sales FOR VALUES IN ('20240616')
      WITH (
        refresh_mode='incremental',
        auto_refresh_enable='true',
        incremental_auto_refresh_schd_start_time='immediate',
        incremental_auto_refresh_interval='30 minutes'
           );
    
    --既存のパーティションを完全更新モードに切り替える
    ALTER DYNAMIC TABLE partition_dt_base_sales_20240615 SET (refresh_mode = 'full');
    --既存のパーティションデータの修正が必要な場合は、更新を実行します。サーバーレスを使用することが望ましいです。
    SET hg_computing_resource = 'serverless';
    REFRESH DYNAMIC TABLE partition_dt_base_sales_20240615;

レガシ構文から新しい構文への変換

Hologres V3.1 では、動的テーブルの作成構文が変更されました。V3.0 からアップグレードした後、新しい構文で動的テーブルを再作成してください。このプロセスを簡素化するための変換ツールが用意されています。

シナリオ

  • 増分動的テーブルは新しい構文で再作成する必要があります。

  • アップグレードチェック中に構文の非互換性が見つかりました。詳細については、アップグレードチェックレポートをご参照ください。

説明

上記のシナリオを除き、V3.0 の動的テーブルは Hologres V3.1 で再作成する必要はありません。ただし、それらに対しては ALTER DYNAMIC TABLE のみ実行できます。CREATE DYNAMIC TABLE (旧構文) は V3.1 以降ではサポートされていません。

制限事項

構文変換コマンドは、非パーティションテーブル (増分および完全更新の両方) に限定されます。V3.0 のパーティション動的テーブルについては、手動で再作成してください。

構文変換が必要な動的テーブルの表示

アップグレード後、インスタンス内で変換が必要なテーブルを見つけます:

非パーティションテーブル

SELECT DISTINCT 
    p.dynamic_table_namespace as table_namespace, 
    p.dynamic_table_name as table_name
FROM hologres.hg_dynamic_table_properties p
JOIN pg_class c ON c.relname = p.dynamic_table_name
JOIN pg_namespace n ON n.oid = c.relnamespace AND n.nspname = p.dynamic_table_namespace
WHERE p.property_key = 'refresh_mode' 
    AND p.property_value = 'incremental'
    AND c.relispartition = false 
    AND c.relkind != 'p';

パーティションテーブル

SELECT DISTINCT 
    pn.nspname as parent_schema,
    pc.relname as parent_name
FROM hologres.hg_dynamic_table_properties p
JOIN pg_class c ON c.relname = p.dynamic_table_name
JOIN pg_namespace n ON n.oid = c.relnamespace AND n.nspname = p.dynamic_table_namespace
JOIN pg_inherits i ON c.oid = i.inhrelid
JOIN pg_class pc ON pc.oid = i.inhparent
JOIN pg_namespace pn ON pn.oid = pc.relnamespace
WHERE p.property_key = 'refresh_mode' 
    AND p.property_value = 'incremental'
    AND c.relispartition = true 
    AND c.relkind != 'p';

構文変換の実行

注意:

  • バージョン要件:V3.1.11 以降。

  • ロール要件:スーパーユーザー。

  • 変換後の動作の変更:

    • 更新モードが auto の場合、自動更新はすぐに開始されます。リソース競合を避けるため、オフピーク時に操作を行ってください。より良い分離のためには、サーバーレスコンピューティングリソースを使用してください。

    • 仮想ウェアハウスインスタンスのリソース使用量の変更:

      • V3.1/V3.2 (新しい構文):動的テーブルの更新は、ベーステーブルと動的テーブルのテーブルグループのプライマリ仮想ウェアハウスのリソースを使用します。

      • V3.0 (レガシ構文) および V4.1 (新しい構文):動的テーブルの更新は、動的テーブルのテーブルグループのプライマリ仮想ウェアハウスのリソースを使用します。

    • 新しい構文では、スケジューリングのために動的テーブルごとに 1 つの接続が追加されます。インスタンスの接続使用率が高い場合は、まずアイドル接続をクリアしてください。

コマンド:

-- 非パーティションテーブル (完全および増分) のみ。
-- 単一の動的テーブルを変換
call hg_dynamic_table_config_upgrade('<table_name>');

-- すべての動的テーブルを変換。注意して使用してください。
call hg_upgrade_all_normal_dynamic_tables();
説明

これらのコマンドは、現在のデータベース内の動的テーブル (旧構文) を新しい構文に変換します。

構文パラメーターマッピング

このコマンドは、V3.0 と V3.1 のパラメーターと値を次のようにマッピングします:

レガシ構文 (V3.0)

新しい構文 (V3.1+)

説明

refresh_mode

auto_refresh_mode

パラメーターの値は変換後も保持されます。例えば、refresh_mode='incremental' は auto_refresh_mode='incremental' になります。

auto_refresh_enable

auto_refresh_enable

パラメーターの値は変換後も保持されます。

{refresh_mode}_auto_refresh_schd_start_time

freshness

auto_refresh_interval の値が freshness の値になります。

例:full_auto_refresh_interval='30 minutes' は freshness='30 minutes' になります。

{refresh_mode}_auto_refresh_interval

{refresh_mode}_guc_hg_computing_resource

computing_resource

パラメーターの値は変換後も保持されます。例:full_guc_hg_computing_resource='serverless' は computing_resource='serverless' になります。

{refresh_mode}guc_hg_experimental_serverless_computing_required_cores

refresh_guc_hg_experimental_serverless_computing_required_cores

パラメーターの値は変換後も保持されます。

{refresh_mode}guc<guc>

refresh_guc<guc_name>

パラメーターの値は変換後も保持されます。例えば、incremental_guc_hg_experimental_max_consumed_rows_per_refresh='1000000' は refresh_guc_hg_experimental_max_consumed_rows_per_refresh='1000000' になります。

テーブルプロパティ (例:orientation)

テーブルプロパティ (例:orientation)

基本的なテーブルプロパティは変更されません。

関連ドキュメント

よくある質問

  • Q:セグメントキーまたはクラスタリングキーが null であるというエラーを修正するにはどうすればよいですか?例:

    ERROR: commit ddl phase1 failed: the index partition key "xxx" should not be nullable
  • 原因:動的テーブルのセグメントキーまたはクラスタリングキーは null 非許容です。これらのキーを設定するルールについては、「イベント時間列 (セグメントキー)」をご参照ください。

  • 解決策:

    1. クラスタリングキーのエラー:Hologres V3.1.26、V3.2.9、V4.0.0 より前のバージョンの場合、インスタンスをアップグレードし、次の GUC を変更して null 許容のクラスタリングキーを許可します:

      -- V3.1 以降の場合
      ALTER DYNAMIC TABLE [ IF EXISTS ] [<schema>.]<table_name> SET
      (refresh_guc_hg_experimental_enable_nullable_segment_key=true);
    2. セグメントキーのエラー:次のコマンドを実行して、null 許容のセグメントキーを許可します。Hologres V4.1 から、セグメントキーはデフォルトで null 許容になったため、エラーを修正するためにインスタンスをアップグレードすることをお勧めします。

      --V3.1 以降の場合、null 許容のクラスタリングキーを許可します
      ALTER DYNAMIC TABLE [ IF EXISTS ] [<schema>.]<table_name> SET
      (refresh_guc_hg_experimental_enable_nullable_clustering_key=true);