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
を指定した場合、作成時に既存のテーブルデータがビューに挿入されます。作成後に挿入されたテーブルデータだけがクエリに含まれます。ビュー作成中にテーブルに挿入されたデータはビューに挿入されないため、POPULATE
を使用することをお勧めしません。
POPULATE
は CREATE TABLE ... AS SELECT ...
のように動作するため、制限があります:
- レプリケートデータベースではサポートされていません
- ClickHouseクラウドではサポートされていません
その代わりに、別の INSERT ... SELECT
を使用できます。
SELECT
クエリには DISTINCT
、GROUP BY
、ORDER BY
、LIMIT
を含めることができます。ここで、該当する変換は挿入された各データブロックで独立して実行されることに注意してください。たとえば、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つの合法的な値があります: DEFINER
、INVOKER
、または NONE
。DEFINER
句では、既存のユーザーまたは CURRENT_USER
を指定できます。
以下の表は、ビューから選択するために必要な権限を示します。
SQL セキュリティオプションに関係なく、すべてのケースで GRANT SELECT ON <view>
を持つことが必要であることに注意してください。
SQL security option | View | Materialized View |
---|---|---|
DEFINER alice | alice はビューのソーステーブルに対して 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
が指定されていない場合、デフォルト値が使用されます:
SQL SECURITY
: 通常のビューにはINVOKER
、マテリアライズドビューにはDEFINER
が指定されます (設定で構成可能)DEFINER
:CURRENT_USER
(設定で構成可能)
ビューが DEFINER
/SQL SECURITY
を指定せずにアタッチされた場合、デフォルト値はマテリアライズドビューに対して SQL SECURITY NONE
、通常のビューに対して SQL SECURITY INVOKER
となります。
既存のビューのSQLセキュリティを変更するには、次のようにします。
Examples
Live View
この機能は廃止予定であり、将来削除される予定です。
便利なことに、古いドキュメントは こちら にあります。
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秒で完了するようになると、再び1分ごとにリフレッシュします。(特に、未実行のリフレッシュのバックログを追いつくために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 HOUR
は source
のリフレッシュ期間よりも短い任意の期間にできます。依存するテーブルは、その依存関係のいずれよりも頻繁にはリフレッシュされません。これは、実際のリフレッシュ期間を1回以上指定することなく、リフレッシュ可能なビューのチェーンを設定する有効な方法です。
他の例をいくつか:
REFRESH EVERY 1 DAY OFFSET 10 MINUTE
(destination
) はREFRESH EVERY 1 DAY
(source
) に依存します。
source
のリフレッシュが10分以上かかる場合、destination
はそれを待ちます。REFRESH EVERY 1 DAY OFFSET 1 HOUR
はREFRESH EVERY 1 DAY OFFSET 23 HOUR
に依存します。
上記と同様で、関連するリフレッシュは異なるカレンダーの日に行われます。destination
のリフレッシュは、source
のリフレッシュがX日目(2時間以上かかる場合)のX+1日に待機します。REFRESH EVERY 2 HOUR
はREFRESH EVERY 1 HOUR
に依存します。
2時間リフレッシュは、他の毎時リフレッシュの後に行われます。たとえば真夜中のリフレッシュの後、次は2時のリフレッシュ、その後のリフレッシュなどです。REFRESH EVERY 1 MINUTE
はREFRESH EVERY 2 HOUR
に依存します。
REFRESH AFTER 1 MINUTE
はREFRESH EVERY 2 HOUR
に依存します。
REFRESH AFTER 1 MINUTE
はREFRESH AFTER 2 HOUR
に依存します。
destination
はsource
のリフレッシュごとに一度リフレッシュされます。つまり、2時間ごとです。1 MINUTE
は実質的に無視されます。REFRESH AFTER 1 HOUR
はREFRESH AFTER 1 HOUR
に依存します。
現在これはお勧めできません。
DEPENDS ON
はリフレッシュ可能なマテリアライズドビュー間でのみ機能します。DEPENDS ON
リストに通常のテーブルをリストすると、そのビューのリフレッシュが行われなくなります(依存関係は ALTER
で削除できます。下記を参照)。
Settings
利用可能なリフレッシュ設定:
refresh_retries
- リフレッシュクエリが例外で失敗した場合、何回リトライするか。すべてのリトライが失敗した場合、次のスケジュールされたリフレッシュ時間にスキップします。0はリトライなし、-1は無限のリトライを意味します。デフォルト: 0。refresh_retry_initial_backoff_ms
- 最初のリトライ前の遅延、refresh_retries
がゼロでない場合。各後続のリトライは遅延を倍増し、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
これは実験的な機能であり、将来のリリースで非互換の変更が加えられる可能性があります。ウィンドウビューと 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
ログテーブル data
で10秒ごとのクリックログの数をカウントするとします。そのテーブル構造は次のとおりです:
最初に、10秒のインターバルでタンブルウィンドウを持つウィンドウビューを作成します:
次に、WATCH
クエリを使用して結果を取得します。
ログがテーブル data
に挿入されると、
WATCH
クエリは次のように結果を出力します:
また、結果をもう1つのテーブルに TO
構文を使ってアタッチすることができます。
追加の例は、ClickHouse の状態を持つテストの中で見つけることができます(そこでは *window_view*
と名付けられています)。
Window View Usage
ウィンドウビューは次のようなシナリオで役立ちます:
- 監視: 時間ごとにメトリックログを集約および計算し、結果をターゲットテーブルに出力します。ダッシュボードはターゲットテーブルをソーステーブルとして使用できます。
- 分析: 時間ウィンドウ内でデータを自動的に集約および前処理します。これは、大量のログを分析する際に便利です。前処理は、複数のクエリでの繰り返し計算を排除し、クエリのレイテンシを減少させます。
Related Content
Temporary Views
ClickHouseは次の特性を持つ一時ビューをサポートします(適用可能な通常のテーブルに従う):
-
セッションの生涯 一時ビューは現在のセッションの間だけ存在します。セッションが終了すると自動的に削除されます。
-
データベースなし 一時ビューにデータベース名を付与することはできません。それはデータベースの外部に存在します(セッション名前空間)。
-
レプリケーションなし / ON CLUSTER不可 一時オブジェクトはセッションにローカルであり、
ON CLUSTER
で作成することはできません。 -
名前解決 一時オブジェクト(テーブルまたはビュー)が永続オブジェクトと同じ名前を持ち、クエリが名前をデータベースなしで参照すると、一時オブジェクトが使用されます。
-
論理オブジェクト(ストレージなし) 一時ビューはその
SELECT
テキストのみを保存します(内部でView
ストレージを使用します)。データを保持せず、INSERT
を受け付けることはできません。 -
エンジンクラウズ
ENGINE
を指定する必要はありません;ENGINE = View
として提供されても、無視されるか同じ論理ビューとして扱われます。 -
セキュリティ / 権限 一時ビューの作成には
CREATE TEMPORARY VIEW
権限が必要で、これはCREATE VIEW
によって暗黙的に付与されます。 -
SHOW CREATE
SHOW CREATE TEMPORARY VIEW view_name;
を使用して一時ビューのDDLを表示します。
Syntax
OR REPLACE
は一時ビューではサポートされていません(通常のテーブルに合わせるため)。一時ビューを“置き換える”必要がある場合は、削除して再作成してください。
Examples
一時ソーステーブルとその上に一時ビューを作成します:
そのDDLを表示します:
それを削除します:
Disallowed / limitations
CREATE OR REPLACE TEMPORARY VIEW ...
→ 許可されていません(DROP
+CREATE
を使用)。CREATE TEMPORARY MATERIALIZED VIEW ...
/LIVE VIEW
/WINDOW VIEW
→ 許可されていません。CREATE TEMPORARY VIEW db.view AS ...
→ 許可されていません(データベース修飾子なし)。CREATE TEMPORARY VIEW view ON CLUSTER 'name' AS ...
→ 許可されていません(一時オブジェクトはセッションローカルです)。POPULATE
、REFRESH
、TO [db.table]
、内部エンジン、および all MV 専用の句 → 一時ビューには適用されません。
Notes on distributed queries
一時 ビュー は単なる定義です; データは渡されるものではありません。あなたの一時ビューが一時 テーブル(例: Memory
)を参照している場合、そのデータは分散クエリの実行時にリモートサーバーに送信できます。これは通常のテーブルと同じ方法で動作します。