動的テーブルを作成する¶
このトピックでは、動的テーブルを作成するためのキーの概念について概説します。
開始する前に、 動的テーブルを作成するための権限 があり、動的テーブルクエリで使用されるすべてのオブジェクトで 変更追跡 が有効になっていることを確認してください。
動的テーブルの作成にはいくつかの制限があります。包括的なリストについては、 動的テーブルの制限 をご参照ください。
変更の追跡を有効にする¶
増分リフレッシュモードで動的テーブルを作成する際、クエリするテーブルで変更追跡が有効になっていない場合、Snowflakeは自動的にそれらのテーブルで変更追跡を有効にしようとします。増分リフレッシュをサポートするには、動的テーブルで使用されるすべての基本オブジェクトに対して、 ゼロ以外のTime Travel保持期間 で変更追跡を有効にする必要があります。
ベースオブジェクトが変われば、動的テーブルも変わります。ベースオブジェクトを再作成する場合は、変更トラッキングを再度有効にする必要があります。
注釈
Snowflakeは、フルリフレッシュモードで作成された動的テーブルの変更追跡を自動的に有効化しようとしません。
特定のデータベースオブジェクトで変更追跡を有効にするには、そのオブジェクトで ALTER TABLE や ALTER VIEW などのコマンドを使用します。動的テーブルを作成するユーザーには、基になるすべてのオブジェクトの変更追跡を有効化する OWNERSHIP 権限が必要です。
変更追跡が有効かどうかを確認するには、基になるオブジェクトに対して SHOW VIEWS、 SHOW TABLES などのコマンドを使用し、 change_tracking 列を調べます。
サポートされるベースオブジェクト¶
動的テーブルは以下のベースオブジェクトをサポートします。
テーブル
Snowflake管理 Apache Iceberg™ テーブル
外部管理 Apache Iceberg™ テーブル
例: 単純な動的テーブルを作成する¶
staging_table という名前のテーブルから product_id 列と product_name 列を含む動的テーブルを作成し、次を決定するとします。
作成した動的テーブル内のデータは、
staging_tableのデータより最大で20分の遅延に設定します。mywhリフレッシュ :ref:`<label-dynamic_tables_intro_refresh_modes> に必要なコンピューティングリソースには、ウェアハウス ` を使用します。リフレッシュモードが自動的に選択されるようにします。
Snowflakeでは、開発中のみ自動リフレッシュモードを使用することを推奨しています。詳細については、 動的なテーブル更新モードを選択するためのベストプラクティス をご参照ください。
動的テーブルを作成時に同期的にリフレッシュしたいと思っています。
リフレッシュタイプが自動的に選択され、動的テーブルが作成時に同期的にリフレッシュされるようにします。
この動的テーブルを作成するには、次の CREATE DYNAMIC TABLE SQL ステートメントを実行します。
CREATE OR REPLACE DYNAMIC TABLE my_dynamic_table
TARGET_LAG = '20 minutes'
WAREHOUSE = mywh
REFRESH_MODE = auto
INITIALIZE = on_create
AS
SELECT product_id, product_name FROM staging_table;
パラメーターの完全なリストとバリアント構文については、 CREATE DYNAMIC TABLE リファレンスをご参照ください。
Snowflake管理または外部管理の Apache Iceberg™ テーブルから読み込む動的テーブルを作成する¶
Icebergテーブルから動的テーブルを作成するのは、通常のテーブルから動的テーブルを作成するのと似ています。Snowflake管理テーブルまたは外部カタログ管理テーブルをベースオブジェクトとして使用し、通常のテーブルの場合と同様に :doc:`/sql-reference/sql/create-dynamic-table`SQL ステートメントを実行します。
Snowflakeが管理するIcebergテーブルをベーステーブルとして読み込む動的テーブルは、Snowflakeが管理するIcebergテーブルのデータをパイプラインに操作させたい場合や、他のエンジンで書き込まれたIcebergテーブルをパイプラインに操作させたい場合に便利です。外部エンジンは、Snowflake管理のIcebergテーブルに書き込めません。Snowflakeでは読み取り/書き込み、外部エンジンでは読み取り専用であることにご注意ください。
AWS GlueやApache Sparkなどのエンジンによって記述された 外部(非Snowflake)カタログ が管理するIcebergテーブルから読み込む動的テーブルは、外部データレイクからのデータを処理するのに役立ちます。外部で管理されたデータの上に動的テーブルを作成し、データを複製したり取り込んだりすることなく、Snowflakeで継続的に処理することができます。
Icebergテーブルを使用する際の制限と考慮事項¶
通常の動的テーブル および 動的Icebergテーブル のすべての制限は引き続き適用されます。
その他の情報は次のとおりです。
Icebergベーステーブルのすべての制限が適用されます。詳細については、 考慮事項と制約 をご参照ください。
Snowflakeネイティブテーブル、Snowflake管理Icebergテーブル、外部管理Icebergテーブルから読み込む動的テーブルを作成できます。
動的テーブルは、行レベルで変更を追跡する他のベーステーブルとは異なり、外部で管理されるIcebergベーステーブルの変更をファイルレベルで追跡します。外部で管理されるIcebergテーブルに対する頻繁なコピーオンライト操作(更新や削除など)は、増分リフレッシュのパフォーマンスに影響を与える可能性があります。
バックフィルを使用して動的テーブルを作成する¶
バックフィルは、動的テーブルでソースデータをすぐに利用できるようにするゼロコピーの低コスト操作です。将来の更新のためにカスタム更新クエリを定義しながら、テーブルまたは動的テーブルから初期データをバックフィルする動的テーブルを作成することができます。
不変性制約を使用すると、不変リージョンのみがバックフィルされ、不変リージョンがソースと一致しなくなっても変更されません。可変リージョンは、通常通り動的テーブルの定義とベーステーブルから計算されます。
Only data defined by the IMMUTABLE WHERE immutability constraint can be backfilled because the backfill data must remain unchanged, even if it differs from the upstream source.
バックフィルの使用例¶
以下の例では、バックフィルされたデータを持つテーブルから新しい動的テーブルを作成する方法を示します。
各列名は、互換性のあるデータ型を持つバックフィルテーブル内で見つかる必要があり、バックフィルテーブルと同じ順序で表示する必要があります。バックフィルテーブルのテーブルプロパティや権限はコピーされません。
Time Travelパラメーター AT | BEFORE が指定されている場合は、指定された時間にバックフィルテーブルからのデータがコピーされます。
例:テーブルの一部からのバックフィル¶
次の例では、my_backfill_table から my_dynamic_table の不変リージョンを、さらに動的テーブルの定義から可変リージョンをバックフィルします。
このシナリオでは、動的テーブルが増分リフレッシュモードで作成された場合、再初期化によって可変のすべての行が削除され、可変のリージョンのみが再入力されます。動的テーブルがフルリフレッシュモードで作成された場合、フルリフレッシュは同じ効果でトリガーされます。
CREATE DYNAMIC TABLE my_dynamic_table (day TIMESTAMP, totalSales NUMBER)
IMMUTABLE WHERE (day < '2025-01-01')
BACKFILL FROM my_backfill_table
TARGET_LAG = '20 minutes'
WAREHOUSE = 'mywh'
AS SELECT DATE_TRUNC('day', ts) AS day, sum(price)
FROM my_base_table
GROUP BY day;
例:バックフィルを使用して、動的テーブルのデータを回復または変更する¶
動的テーブルのデータや定義を直接編集することはできません。データを回復または修正するには、次の回避策の手順を完了します。
動的テーブルを通常のテーブルにクローンします。
必要に応じて、クローンされたテーブルを変更します。
編集されたテーブルから新しい動的テーブルにバックフィルします。
次の例では my_dynamic_table が sales ベーステーブルから日次販売データを集計します。
CREATE OR REPLACE TABLE sales(item_id INT, ts TIMESTAMP, sales_price FLOAT);
INSERT INTO sales VALUES (1, '2025-05-01 01:00:00', 10.0), (1, '2025-05-01 02:00:00', 15.0), (1, '2025-05-01 03:00:00', 11.0);
INSERT INTO sales VALUES (1, '2025-05-02 00:00:00', 11.0), (1, '2025-05-02 05:00:00', 13.0);
CREATE DYNAMIC TABLE my_dynamic_table
TARGET_LAG = 'DOWNSTREAM'
WAREHOUSE = mywh
INITIALIZE = on_create
IMMUTABLE WHERE (day <= '2025-05-01')
AS
SELECT item_id, date_trunc('DAY', ts) day, count(sales_price) AS sales_count FROM sales
GROUP BY item_id, day;
SELECT item_id, to_char(day, 'YYYY-MM-DD') AS day, sales_count FROM my_dynamic_table;
+---------+------------+-------------+
| ITEM_ID | DAY | SALES_COUNT |
|---------+------------+-------------|
| 1 | 2025-05-01 | 3 |
| 1 | 2025-05-02 | 2 |
+---------+------------+-------------+
オプションで、古いデータをアーカイブしてストレージコストを節約できます。
DELETE FROM sales WHERE ts < '2025-05-02';
ALTER DYNAMIC TABLE my_dynamic_table REFRESH;
SELECT item_id, to_char(day, 'YYYY-MM-DD') AS day, sales_count FROM my_dynamic_table;
その後、2025-05-01 で販売エラーを見つけます。条件: sales_count は2である必要があります。これを修正するには
my_dynamic_tableを通常のテーブルにクローンします。CREATE OR REPLACE TABLE my_dt_clone_table CLONE my_dynamic_table;
クローンされたテーブルを更新します。
UPDATE my_dt_clone_table SET sales_count = 2 WHERE day = '2025-05-01'; SELECT item_id, to_char(day, 'YYYY-MM-DD') AS day, sales_count FROM my_dt_clone_table;
+---------+------------+-------------+ | ITEM_ID | DAY | SALES_COUNT | |---------+------------+-------------| | 1 | 2025-05-01 | 2 | | 1 | 2025-05-02 | 2 | +---------+------------+-------------+
編集されたクローンをバックフィルのソースとして使用し、動的テーブルを再作成します。
CREATE OR REPLACE DYNAMIC TABLE my_dynamic_table BACKFILL FROM my_dt_clone_table IMMUTABLE WHERE (day <= '2025-05-01') TARGET_LAG = 'DOWNSTREAM' WAREHOUSE = mywh INITIALIZE = on_create AS SELECT item_id, date_trunc('DAY', ts) day, count(sales_price) AS sales_count FROM sales GROUP BY item_id, day;
このアプローチにより、ベーステーブルを変更することなく、動的テーブルのデータを回復または修正できます。
SELECT item_id, to_char(day, 'YYYY-MM-DD') AS day, sales_count FROM my_dynamic_table;
+---------+------------+-------------+ | ITEM_ID | DAY | SALES_COUNT | |---------+------------+-------------| | 1 | 2025-05-01 | 2 | | 1 | 2025-05-02 | 2 | +---------+------------+-------------+
例:バックフィルを使用して動的テーブルのスキーマを変更する¶
動的テーブルのスキーマを直接変更することはできません。スキーマを更新する場合(たとえば、列を追加するなど)は、次のステップに従います。
動的テーブルを通常のテーブルにクローンします。次の例では、
sales`(:ref:`上記 <label-data-surgery-example>)から作成したmy_dynamic_tableを使用します。CREATE OR REPLACE TABLE my_dt_clone_table CLONE my_dynamic_table;
クローンされたテーブルのスキーマを変更します。
ALTER TABLE my_dt_clone_table ADD COLUMN sales_avg FLOAT; SELECT item_id, to_char(day, 'YYYY-MM-DD') as DAY, SALES_COUNT, SALES_AVG FROM my_dt_clone_table;
オプションで、新しい列にデータを入力します。
編集されたクローンをバックフィルのソースとして使用し、動的テーブルを再作成します。
CREATE OR REPLACE DYNAMIC TABLE my_dynamic_table BACKFILL FROM my_dt_clone_table IMMUTABLE WHERE (day <= '2025-05-01') TARGET_LAG = 'DOWNSTREAM' WAREHOUSE = mywh INITIALIZE = on_create AS SELECT item_id, date_trunc('DAY', ts) day, count(sales_price) AS sales_count, avg(sales_price) as sales_avg FROM sales GROUP BY item_id, day;
このアプローチにより、ベーステーブルを変更することなく、動的テーブルのデータを回復または修正できます。
SELECT item_id, to_char(day, 'YYYY-MM-DD') as DAY, SALES_COUNT, SALES_AVG, metadata$is_immutable as IMMUTABLE from my_dynamic_table ORDER BY ITEM_ID, DAY;
+---------+------------+-------------+-----------+-----------+ | ITEM_ID | DAY | SALES_COUNT | SALES_AVG | IMMUTABLE | |---------+------------+-------------|-----------|-----------| | 1 | 2025-05-01 | 3 | NULL | TRUE | | 1 | 2025-05-02 | 2 | 12 | FALSE | +---------+-------------+------------+-----------+-----------+
バックフィルされたデータで動的テーブルを作成する際の制限と考慮事項¶
通常の動的テーブルの制限 および 不変性制約の制限 はすべて、引き続き適用されます。
次の追加制限と考慮事項が適用されます。
現在、バックフィルに使用できるのは通常のテーブルと動的テーブルのみです。
ポリシーやタグはバックフィルテーブルからコピーされるため、新しい動的テーブルでは指定できません。
新しい動的テーブルとバックフィルテーブルのクラスタリングキーは同じである必要があります。
動的テーブル作成のベストプラクティス¶
動的テーブルのパイプラインのチェーン¶
新しい動的テーブルを定義する場合、多くの入れ子ステートメントを持つ大きな動的テーブルを定義するのではなく、パイプラインを持つ小さな動的テーブルを使用します。
動的テーブルを設定して、他の動的テーブルをクエリできます。たとえば、データパイプラインがステージングテーブルからデータを抽出して、さまざまなディメンションテーブル(customer、product、date、および:code:time`など)を更新するシナリオを想像してください。さらに、パイプラインはこれらのディメンションテーブルの情報に基づいて、:code:`sales 集計テーブルを更新します。ディメンションテーブルがステージングテーブルにクエリし、sales 集計テーブルがディメンションテーブルにクエリするように構成することで、タスクグラフと同様のカスケード効果が得られます。
この設定では、sales 集計テーブルのリフレッシュは、ディメンションテーブルのリフレッシュが正常に完了した後にのみ実行されます。これにより、データの一貫性が確保され、ラグターゲットが達成されます。自動化されたリフレッシュプロセスにより、ソーステーブルの変更は適切なタイミングですべての従属テーブルのリフレッシュをトリガーします。
複雑なタスクグラフに「コントローラー」動的テーブルを使用する¶
多くのルートとリーフを持つ動的テーブルの複雑なグラフがあり、1つのコマンドでタスクグラフ全体に対して操作(ラグ変更、手動リフレッシュ、中断など)を実行したい場合、以下を実行します。
すべての動的テーブルの
TARGET_LAGの値をDOWNSTREAMに設定してください。タスクグラフのすべてのリーフから読み取る「コントローラー」動的テーブルを作成します。このコントローラーがリソースを消費しないようにするには、以下を実行します。
CREATE DYNAMIC TABLE controller TARGET_LAG = <target_lag> WAREHOUSE = <warehouse> AS SELECT 1 A FROM <leaf1>, …, <leafN> LIMIT 0;
コントローラーを使用してグラフ全体を制御します。例:
タスクグラフの新しいターゲットラグを設定します。
ALTER DYNAMIC TABLE controller SET TARGET_LAG = <new_target_lag>;タスクグラフを手動でリフレッシュします。
ALTER DYNAMIC TABLE controller REFRESH;
一時動的テーブルを使用してストレージコストを削減する¶
一時 動的テーブルは、データ保持期間内はデータを確実に保持し、Time Travelをサポートしますが、フェイルセーフ期間を超えてデータを保持することはありません。デフォルトでは、動的テーブルデータは fail-safe ストレージに7日間保持されます。
リフレッシュスループットが高い動的テーブルでは、ストレージの消費量が大幅に増加する可能性があります。したがって、動的テーブルを一時的に使用するのは、そのデータが永続テーブルと同じレベルのデータ保護とリカバリを必要としない場合に限ります。
一時動的テーブルを作成したり、既存の動的テーブルを一時的な動的テーブルにクローンするには、 CREATE DYNAMIC TABLE ステートメントを使用します。
動的テーブル作成のトラブルシューティング¶
動的テーブルを作成すると、初期リフレッシュはスケジュール(ON_SCHEDULE)または作成時すぐに(ON_CREATE)発生します。初期データ入力、つまり 初期化 は、この初期リフレッシュがいつ発生するかによって決まります。たとえば ON_CREATE では、初期化が上流の動的テーブルのリフレッシュをトリガーする場合、初期化に時間がかかる可能性があります。
スキャンされるデータの量に応じて、初期化に時間がかかる場合があります。進行状況を表示するには、以下を実行します。
Snowsight にサインインします。
ナビゲーションメニューで Monitoring » Query History を選択します。
Filters ドロップダウンで、 SQL Text フィルターに CREATE DYNAMIC TABLE と入力し、 Warehouse フィルターにウェアハウス名を入力します。
SQL text で動的テーブルを含むクエリを選択し、 Query Details と Query Profile タブを使用して進行状況を追跡します。