メインコンテンツまでスキップ
メインコンテンツまでスキップ

CREATE VIEW

新しいビューを作成します。ビューは、通常の物化ついリフレッシュ可能な物化ビュー、および ウィンドウ(リフレッシュ可能な物化ビューとウィンドウビューは実験的機能です)として作成できます。

Normal View

構文:

通常のビューはデータを保存していません。アクセスのたびに別のテーブルから読み取るだけです。言い換えれば、通常のビューは保存されたクエリに過ぎません。ビューから読み取るとき、この保存されたクエリがFROM句のサブクエリとして使用されます。

例として、次のようにビューを作成したと仮定しましょう:

そして、クエリを次のように書きます:

このクエリは、サブクエリを使用した場合と完全に同等です:

Parameterized View

パラメータ化されたビューは通常のビューに似ていますが、すぐには解決されないパラメータと共に作成することができます。これらのビューは、テーブル関数と共に使用でき、ビューの名前を関数名として、パラメータ値を引数として指定します。

上記は、パラメータを次のように置き換えることで、テーブル関数として使用できるビューを作成します。

Materialized View

ヒント

物化ビューの使用に関する手順ガイドです。

物化ビューは、対応するSELECTクエリによって変換されたデータを格納します。

TO [db].[table]なしで物化ビューを作成する場合、データを格納するためのテーブルエンジンであるENGINEを指定する必要があります。

TO [db].[table]を使用して物化ビューを作成する場合、POPULATEを同時に使用することはできません。

物化ビューは次のように実装されます: SELECTで指定されたテーブルにデータを挿入するとき、挿入されたデータの一部はこのSELECTクエリによって変換され、結果はビューに挿入されます。

注記

ClickHouseの物化ビューは、データを宛先テーブルに挿入する際にカラム名を使用します。SELECTクエリの結果に存在しないカラム名がある場合、ClickHouseはデフォルト値を使用します。たとえカラムがNullableでなくても、これは変わりません。物化ビューを使用する際は、各カラムにエイリアスを追加するのが安全な作業です。

ClickHouseの物化ビューは、挿入トリガーとしてより実装されています。ビュークエリに集約が含まれている場合、それは新しく挿入されたデータのバッチにのみ適用されます。基のテーブルの既存のデータに対する変更(更新、削除、パーティションのドロップなど)は、物化ビューを変更しません。

ClickHouseの物化ビューは、エラーが発生した場合に決定的な動作を持ちません。これは、すでに書き込まれたブロックは宛先テーブルに保持されますが、エラー以降のすべてのブロックが保持されないことを意味します。

デフォルトでは、いずれかのビューへのプシュが失敗すると、INSERTクエリも失敗し、一部のブロックが宛先テーブルに書き込まれない可能性があります。これをmaterialized_views_ignore_errors設定を使用して変更できます(この設定はINSERTクエリに対して設定する必要があります)。materialized_views_ignore_errors=trueを設定すると、ビューへのプッシュ中のすべてのエラーが無視され、すべてのブロックが宛先テーブルに書き込まれます。

また、materialized_views_ignore_errorsは、デフォルトでsystem.*_logテーブルに対してtrueに設定されています。

POPULATEを指定すると、既存のテーブルデータがビューに挿入され、CREATE TABLE ... AS SELECT ...を行うかのようになります。そうでない場合、クエリにはビュー作成後にテーブルに挿入されたデータのみが含まれます。データがビュー作成中にテーブルに挿入されるため、POPULATEの使用は推奨しません

注記

POPULATECREATE TABLE ... AS SELECT ...のように機能するため、制限があります:

  • レプリケーションデータベースではサポートされていません。
  • ClickHouseクラウドではサポートされていません。

代わりに、別のINSERT ... SELECTを使用できます。

SELECTクエリは、DISTINCTGROUP BYORDER BYLIMITを含めることができます。対応する変換は挿入されたデータの各ブロックに対して独立して実行されることに注意してください。たとえば、GROUP BYが設定されている場合、データは挿入中に集約されますが、挿入されたデータの単一のパケット内のみです。データはさらに集約されることはありません。例外は、SummingMergeTreeのようにデータ集約を独自に実行するENGINEを使用するときです。

物化ビューに対するALTERクエリの実行には制限があります。たとえば、SELECTクエリを更新することはできないため、不便な場合があります。物化ビューがTO [db.]name構造を使用している場合、ビューをDETACHし、ターゲットテーブルに対してALTERを実行し、その後以前にDETACHしたビューをATTACHできます。

物化ビューはoptimize_on_insert設定の影響を受けることに注意してください。データはビューへの挿入前にマージされます。

ビューは通常のテーブルと同様に見えます。たとえば、SHOW TABLESクエリの結果にリストされます。

ビューを削除するには、DROP VIEWを使用します。DROP TABLEもビューに対して機能します。

SQL security

DEFINERおよびSQL SECURITYを使用すると、ビューの基となるクエリを実行する際に使用するClickHouseユーザーを指定できます。 SQL SECURITYには3つの合法的な値があります: DEFINERINVOKER、またはNONEDEFINER句では、任意の既存のユーザーまたはCURRENT_USERを指定できます。

以下の表は、ビューから選択するために必要なユーザーごとの権限を説明します。 SQLセキュリティオプションに関係なく、読み取るには常にGRANT SELECT ON <view>が必要であることに注意してください。

SQLセキュリティオプションビュー物化ビュー
DEFINER alicealiceはビューのソーステーブルに対してSELECT権限を持っている必要があります。aliceはビューのソーステーブルに対してSELECT権限を持っていて、ビューのターゲットテーブルに対してINSERT権限も必要です。
INVOKERユーザーはビューのソーステーブルに対してSELECT権限を持っている必要があります。SQL SECURITY INVOKERは物化ビューに対して指定できません。
NONE--
注記

SQL SECURITY NONEは非推奨のオプションです。SQL SECURITY NONEでビューを作成する権限を持つユーザーは、任意のクエリを実行することができます。 したがって、このオプションでビューを作成するには、GRANT ALLOW SQL SECURITY NONE TO <user>が必要です。

DEFINER/SQL SECURITYが指定されていない場合、デフォルト値が使用されます:

DEFINER/SQL SECURITYが指定されていないビューがアタッチされている場合、物化ビューに対するデフォルト値はSQL SECURITY NONE、通常のビューに対するデフォルト値はSQL SECURITY INVOKERです。

既存のビューのSQLセキュリティを変更するには、次のように使用します。

Examples

Live View

Deprecated feature

この機能は非推奨であり、将来的に削除される予定です。

お手数ですが、旧ドキュメントはこちらにあります。

Refreshable Materialized View

ここで、intervalは単純なインターバルのシーケンスです:

定期的に対応するクエリを実行し、その結果をテーブルに格納します。

  • クエリがAPPENDと言った場合、各リフレッシュは既存の行を削除せずにテーブルに行を挿入します。挿入は原子的ではなく、通常のINSERT SELECTと同様です。
  • さもなくば、各リフレッシュはテーブルの以前の内容を原子的に置き換えます。

リフレッシュ可能な物化ビューの通常の非リフレッシュ可能な物化ビューとの違い:

  • 挿入トリガーがありません。つまり、SELECTで指定されたテーブルに新しいデータが挿入されると、自動的にリフレッシュ可能な物化ビューにプッシュされません。定期的なリフレッシュはクエリ全体を実行します。
  • SELECTクエリに制限はありません。テーブル関数(例:url())、ビュー、UNION、JOINがすべて許可されています。
注記

REFRESH ... SETTINGS部分のクエリ内の設定はリフレッシュ設定(例:refresh_retries)であり、通常の設定(例:max_threads)とは異なります。通常の設定は、クエリの最後にSETTINGSを使用して指定できます。

Refresh Schedule

リフレッシュスケジュールの例:

RANDOMIZE FORは、各リフレッシュの時間をランダムに調整します。例:

与えられたビューに対しては、同時に1回だけリフレッシュを実行できます。例えば、REFRESH EVERY 1 MINUTEのビューがリフレッシュに2分かかると、リフレッシュは2分ごとに行われます。高速になり、10秒でリフレッシュを開始すると、再度毎分リフレッシュされます(特に、バックログのリフレッシュを追いかけるために毎10秒リフレッシュされるわけではない - そのようなバックログはありません)。

加えて、物化ビューが作成された直後にリフレッシュが開始されます。CREATEクエリにEMPTYが指定されている場合、最初のリフレッシュはスケジュールに従って行われます。

In Replicated DB

リフレッシュ可能な物化ビューがレプリケートデータベースにある場合、レプリカは調整し合い、毎回のスケジュールで1つのレプリカだけがリフレッシュを実行します。ReplicatedMergeTreeテーブルエンジンが必要であり、すべてのレプリカはリフレッシュで生成されたデータを確認します。

APPENDモードでは、SETTINGS all_replicas = 1を使用して調整を無効にできます。これにより、レプリカは互いに独立してリフレッシュを行います。この場合、ReplicatedMergeTreeは必要ありません。

APPENDモードでは、調整されたリフレッシュのみがサポートされています。非調整の場合は、AtomicデータベースおよびCREATE ... ON CLUSTERクエリを使用して、すべてのレプリカにリフレッシュ可能な物化ビューを作成します。

調整はKeeperを介して行われます。znodeのパスはdefault_replica_pathサーバー設定によって決定されます。

Dependencies

DEPENDS ONは異なるテーブルのリフレッシュを同期させます。例として、次のような2つのリフレッシブルな物化ビューのチェーンを考えてみてください:

DEPENDS ONがない場合、両方のビューは真夜中にリフレッシュを開始し、destinationは通常、sourceの昨日のデータを見ます。依存関係を追加すると:

この場合、destinationのリフレッシュはその日のsourceのリフレッシュが終了した後にのみ開始されるため、destinationは新しいデータに基づいて更新されます。

あるいは、次のように実現できます:

ここで、1 HOURsourceのリフレッシュ期間より短い任意の期間で構いません。依存しているテーブルは、その依存関係よりも頻繁にはリフレッシュされません。これは、実際のリフレッシュ期間を1回以上指定することなく、リフレッシュ可能なビューのチェーンを設定するための有効な方法です。

他のいくつかの例:

  • REFRESH EVERY 1 DAY OFFSET 10 MINUTEdestination)はREFRESH EVERY 1 DAYsource)に依存します。
    sourceのリフレッシュが10分以上かかる場合、destinationはそれを待ちます。
  • REFRESH EVERY 1 DAY OFFSET 1 HOURREFRESH EVERY 1 DAY OFFSET 23 HOURに依存します。
    上記のように、対応するリフレッシュが異なるカレンダーの日に発生しても、destinationのリフレッシュはX+1の日でsourceのリフレッシュがXの日(2時間以上かかる場合)の完了を待ちます。
  • REFRESH EVERY 2 HOURREFRESH EVERY 1 HOURに依存します。
    2 HOURリフレッシュは、毎時リフレッシュした後に行われます(真夜中のリフレッシュ後、次の2時のリフレッシュ後など)。
  • REFRESH EVERY 1 MINUTEREFRESH EVERY 2 HOURに依存します。
    REFRESH AFTER 1 MINUTEREFRESH EVERY 2 HOURに依存します。
    REFRESH AFTER 1 MINUTEREFRESH AFTER 2 HOURに依存します。
    destinationは、毎回のsourceリフレッシュの後、すなわち2時間ごとに更新されます。1 MINUTEは実質的に無視されます。
  • REFRESH AFTER 1 HOURREFRESH AFTER 1 HOURに依存します。
    現在これは推奨されていません。
注記

DEPENDS ONは、リフレッシュ可能な物化ビューの間でのみ機能します。DEPENDS ONリストに通常のテーブルを記載すると、そのビューは永遠にリフレッシュしなくなります(依存関係はALTERによって削除できます)。

Settings

利用可能なリフレッシュ設定:

  • refresh_retries - リフレッシュクエリが例外で失敗した場合のリトライ回数。すべてのリトライが失敗した場合、次のスケジュールされたリフレッシュ時間にスキップします。0はリトライなし、-1は無限リトライを意味します。デフォルト:0。
  • refresh_retry_initial_backoff_ms - 最初のリトライ前の遅延で、refresh_retriesがゼロでない場合。各次のリトライが遅延を2倍にし、refresh_retry_max_backoff_msまで成長します。デフォルト:100 ms。
  • refresh_retry_max_backoff_ms - リフレッシュ試行間の遅延の指数的成長の制限。デフォルト:60000 ms(1分)。

Changing Refresh Parameters

リフレッシュパラメータを変更するには:

注記

これにより、すべてのリフレッシュパラメータ(スケジュール、依存関係、設定、およびAPPENDの有無)が一度に置き換えられます。たとえば、テーブルにDEPENDS ONがあった場合、DEPENDS ONなしでMODIFY REFRESHを行うと、依存関係が削除されます。

Other operations

すべてのリフレッシュ可能な物化ビューの状態は、テーブルsystem.view_refreshesで利用できます。特に、リフレッシュの進行状況(実行中の場合)、最後のリフレッシュ時間、次のリフレッシュ時間、リフレッシュが失敗した場合の例外メッセージが含まれます。

リフレッシュを手動で停止、開始、トリガー、またはキャンセルするにはSYSTEM STOP|START|REFRESH|WAIT|CANCEL VIEWを使用します。

リフレッシュの完了を待つにはSYSTEM WAIT VIEWを使用します。特に、ビュー作成後の初期リフレッシュの待機に役立ちます。

注記

面白い事実:リフレッシュクエリは、リフレッシュされているビューから読み取ることが許可されています。つまり、データのリフレッシュ前のバージョンを見ることができます。これにより、コンウェイのライフゲームを実装できます:https://pastila.nl/?00021a4b/d6156ff819c83d490ad2dcec05676865#O0LGWTO7maUQIA4AcGUtlA==

Window View

Experimental feature. Learn more.
Not supported in ClickHouse Cloud
参考

これは実験的な機能であり、将来のリリースで後方互換性のない方法で変更される可能性があります。ウィンドウビューとWATCHクエリの使用を有効にするには、allow_experimental_window_view設定を使用します。コマンド set allow_experimental_window_view = 1 を入力してください。

ウィンドウビューは、時間ウィンドウでデータを集約し、ウィンドウが発火する準備が整ったときにその結果を出力できます。レイテンシを削減するために中間集約結果を内側(または指定された)テーブルに保存し、指定されたテーブルに処理結果をプッシュしたり、WATCHクエリを使用してプッシュ通知を行ったりできます。

ウィンドウビューの作成は、MATERIALIZED VIEWの作成に似ています。ウィンドウビューには中間データを保存するための内側ストレージエンジンが必要です。内側ストレージは、INNER ENGINE句を使用して指定できます。デフォルトの内側エンジンはAggregatingMergeTreeです。

TO [db].[table]なしでウィンドウビューを作成する場合、データを格納するためのテーブルエンジンであるENGINEを指定する必要があります。

Time Window Functions

時間ウィンドウ関数は、レコードの下限および上限ウィンドウを取得するために使用されます。ウィンドウビューは、時間ウィンドウ関数と共に使用する必要があります。

TIME ATTRIBUTES

ウィンドウビューは処理時間イベント時間の処理をサポートしています。

処理時間は、ウィンドウビューがローカルマシンの時間に基づいて結果を生成できるようにし、デフォルトで使用されます。これは最も直接的な時間の定義ですが、決定論的ではありません。処理時間属性は、時間ウィンドウ関数のtime_attrをテーブルのカラムに設定することによって、またはnow()関数を使用することによって定義できます。以下のクエリは、処理時間でウィンドウビューを作成します。

イベント時間は、各個別のイベントが生成装置で発生した時刻を指します。この時間は通常、生成されるときにレコードに埋め込まれます。イベント時間処理は、順序が乱れたイベントや遅延イベントが発生した場合でも一貫した結果を可能にします。ウィンドウビューはWATERMARK構文を使用することで、イベント時間処理をサポートします。

ウィンドウビューは3つのウォーターマーク戦略を提供します:

  • STRICTLY_ASCENDING:これまでに観測された最大のタイムスタンプのウォーターマークを発行します。最大タイムスタンプよりも小さいタイムスタンプを持つ行は遅れたものではありません。
  • ASCENDING:これまでに観測された最大のタイムスタンプのウォーターマークを発行しますが、1を引きます。最大タイムスタンプと同じか小さいタイムスタンプを持つ行は遅れたものではありません。
  • BOUNDED:WATERMARK=INTERVAL。指定した遅延を引いた最大の観測されたタイムスタンプをウォーターマークとして発行します。

以下のクエリは、WATERMARKを使用してウィンドウビューを作成する例です:

デフォルトでは、ウォーターマークが到達したときにウィンドウが発火し、ウォーターマークを超えて到着した要素は破棄されます。ウィンドウビューは、ALLOWED_LATENESS=INTERVALを設定することで遅延イベント処理をサポートします。遅延処理の一例は以下の通りです:

遅れて発生した要素から出力される結果は、以前の計算の更新された結果として処理されるべきです。ウィンドウの終了時ではなく、遅延イベントが到着したときにウィンドウビューは即座に発火します。このため、同じウィンドウに複数の出力が結果として生じます。ユーザーはこれらの重複結果を考慮するか、重複排除を行う必要があります。

ウィンドウビューで指定されたSELECTクエリを変更するには、ALTER TABLE ... MODIFY QUERYステートメントを使用します。更新されたSELECTクエリから得られるデータ構造は、TO [db.]name句の有無にかかわらず元のSELECTクエリと同様である必要があります。中間状態が再利用できないため、現在のウィンドウのデータは失われることに注意してください。

Monitoring New Windows

ウィンドウビューは、変更を監視するためにWATCHクエリをサポートします。また、結果をテーブルに出力するためにTO構文を使用できます。

WATCHクエリは、LIVE VIEWと似た動作をします。受信する更新の数を指定するためにLIMITを設定できます。EVENTS句を使用すると、クエリの結果の代わりに最新のクエリのウォーターマークのみを取得する短い形式のWATCHクエリを取得できます。

Settings

  • window_view_clean_interval: 古いデータを解放するためのウィンドウビューのクリーン間隔(秒単位)。システムは、システム時間またはWATERMARK設定に従って完全にトリガーされていないウィンドウを保持し、その他のデータは削除されます。
  • window_view_heartbeat_interval: ウォッチクエリが生存していることを示すためのハートビート間隔(秒単位)。
  • wait_for_window_view_fire_signal_timeout: イベント時間処理におけるウィンドウビューの発火信号を待つためのタイムアウト。

Example

クリックログを10秒ごとにカウントする必要があると仮定し、ログテーブルの構造は次のようになります。

まず、10秒間隔のタンブルウィンドウでウィンドウビューを作成します。

次に、WATCHクエリを使用して結果を取得します。

データテーブルにログが挿入されるとき、

WATCHクエリは、以下の結果を印刷するはずです:

代わりに、TO構文を使用して出力を別のテーブルに接続できます。

追加の例は、ClickHouseのステートフルテスト群の中にあります(それらは*window_view*という名前です)。

Window View Usage

ウィンドウビューは、以下のシナリオで役立ちます:

  • 監視: 時間ごとにメトリクスログを集約し計算し、結果をターゲットテーブルに出力します。ダッシュボードはターゲットテーブルをソーステーブルとして使用できます。
  • 分析: 時間ウィンドウ内でデータを自動的に集約し前処理します。これは、多くのログを分析する際に便利です。前処理は、複数のクエリでの計算の繰り返しを排除し、クエリのレイテンシを削減します。