> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> CREATE VIEW に関するドキュメント

# CREATE VIEW

export const DeprecatedBadge = () => {
  return <div className="deprecatedBadge">
            <div className="deprecatedIcon">
            <svg width="14" height="10" viewBox="0 0 14 10" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M13 0H1C0.734784 0 0.48043 0.105357 0.292893 0.292893C0.105357 0.48043 0 0.734784 0 1V2.5C0 2.76522 0.105357 3.01957 0.292893 3.20711C0.48043 3.39464 0.734784 3.5 1 3.5V9C1 9.26522 1.10536 9.51957 1.29289 9.70711C1.48043 9.89464 1.73478 10 2 10H12C12.2652 10 12.5196 9.89464 12.7071 9.70711C12.8946 9.51957 13 9.26522 13 9V3.5C13.2652 3.5 13.5196 3.39464 13.7071 3.20711C13.8946 3.01957 14 2.76522 14 2.5V1C14 0.734784 13.8946 0.48043 13.7071 0.292893C13.5196 0.105357 13.2652 0 13 0ZM12 9H2V3.5H12V9ZM13 2.5H1V1H13V2.5ZM5 5.5C5 5.36739 5.05268 5.24021 5.14645 5.14645C5.24021 5.05268 5.36739 5 5.5 5H8.5C8.63261 5 8.75979 5.05268 8.85355 5.14645C8.94732 5.24021 9 5.36739 9 5.5C9 5.63261 8.94732 5.75979 8.85355 5.85355C8.75979 5.94732 8.63261 6 8.5 6H5.5C5.36739 6 5.24021 5.94732 5.14645 5.85355C5.05268 5.75979 5 5.63261 5 5.5Z" fill="currentColor" />
            </svg>
        </div>
            非推奨機能
        </div>;
};

新しいビューを作成します。ビューには、[通常ビュー](#normal-view)、[materialized view](#materialized-view)、および[リフレッシャブルmaterialized view](#refreshable-materialized-view)があります。

## 通常ビュー

構文:

```sql theme={null}
CREATE [OR REPLACE] VIEW [IF NOT EXISTS] [db.]table_name [(alias1 [, alias2 ...])] [ON CLUSTER cluster_name]
[DEFINER = { user | CURRENT_USER }] [SQL SECURITY { DEFINER | INVOKER | NONE }]
AS SELECT ...
[COMMENT 'comment']
```

通常のビューはデータを一切保存しません。アクセスされるたびに、別のテーブルから読み取るだけです。つまり、通常のビューは単なる保存クエリにすぎません。ビューから読み取る際には、この保存クエリが [FROM](/ja/reference/statements/select/from) 句内のサブクエリとして使用されます。

例として、次のようなビューを作成したとします。

```sql theme={null}
CREATE VIEW view AS SELECT ...
```

そして、クエリを記述します:

```sql theme={null}
SELECT a, b, c FROM view
```

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

```sql theme={null}
SELECT a, b, c FROM (SELECT ...)
```

## パラメーター化ビュー

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

```sql theme={null}
CREATE VIEW view AS SELECT * FROM TABLE WHERE Column1={column1:datatype1} and Column2={column2:datatype2} ...
```

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

```sql theme={null}
SELECT * FROM view(column1=value1, column2=value2 ...)
```

パラメーター化ビューはパラメーター値に依存するため、パラメーターが指定されていない場合はスキーマを持ちません。
つまり、`system.columns` テーブルにはパラメーター化ビューに関する情報はありません。
また、`DESCRIBE` クエリはパラメーターが指定されている場合にのみ機能します。

```sql theme={null}
DESCRIBE view(column1=value1, column2=value2 ...)
```

## Materialized View

```sql theme={null}
CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster_name] [TO[db.]name [(columns)]] [ENGINE = engine] [POPULATE]
[REFRESH ...]
[DEFINER = { user | CURRENT_USER }] [SQL SECURITY { DEFINER | NONE }]
AS SELECT ...
[COMMENT 'comment']
```

```sql theme={null}
CREATE OR REPLACE MATERIALIZED VIEW [db.]table_name [ON CLUSTER cluster_name] [TO[db.]name [(columns)]] [ENGINE = engine] [POPULATE]
[REFRESH ...]
[DEFINER = { user | CURRENT_USER }] [SQL SECURITY { DEFINER | NONE }]
AS SELECT ...
[COMMENT 'comment']
```

`OR REPLACE` と `IF NOT EXISTS` は相互に排他的であり、組み合わせると構文エラーになります。

### CREATE OR REPLACE MATERIALIZED VIEW

`CREATE OR REPLACE MATERIALIZED VIEW` は、既存のmaterialized viewと、その内部ストレージテーブル (存在する場合) をアトミックに置き換えます。この操作には、`Atomic` または `Replicated` データベースエンジンが必要です。

```sql theme={null}
CREATE OR REPLACE MATERIALIZED VIEW [db.]name [ON CLUSTER cluster]
[TO [db.]target_table]
[ENGINE = engine]
[POPULATE]
[REFRESH ...]
AS SELECT ...
```

主な動作:

* **`TO` 句なし**: 古い内部テーブルは削除され、新しい内部テーブルが作成されます。`POPULATE` が指定されていない限り、内部テーブル内の既存データは失われます。
* **`TO` 句あり**: 置き換えられるのはビュー定義のみです。ターゲットテーブルとそのデータには影響しません。
* `REFRESH`、`ON CLUSTER`、およびすべてのエンジンオプションに対応しています。`POPULATE` は `Atomic` データベースでのみサポートされ、`Replicated` データベースでは使用できません (以下の `POPULATE` に関する注記を参照) 。
* `CREATE VIEW` 権限と `DROP VIEW` 権限が必要です。

<Note>
  `CREATE OR REPLACE MATERIALIZED VIEW` は、`Atomic` または `Replicated` データベースエンジンでのみサポートされます。`Ordinary` データベースエンジンではサポートされません。
</Note>

**例:**

```sql theme={null}
-- Create a materialized view with an inner table
CREATE OR REPLACE MATERIALIZED VIEW mv
    ENGINE = MergeTree ORDER BY x
    AS SELECT x, sum(y) AS total FROM src GROUP BY x;

-- Replace with a new definition (old inner table data is lost)
CREATE OR REPLACE MATERIALIZED VIEW mv
    ENGINE = MergeTree ORDER BY x
    AS SELECT x, count() AS cnt FROM src GROUP BY x;

-- Replace with POPULATE to backfill from existing source data
CREATE OR REPLACE MATERIALIZED VIEW mv
    ENGINE = MergeTree ORDER BY x
    POPULATE
    AS SELECT x FROM src;

-- Replace an inner-table MV with a TO-table MV (target data is preserved)
CREATE OR REPLACE MATERIALIZED VIEW mv TO target
    AS SELECT x FROM src;
```

<Tip>
  [materialized view](/ja/concepts/features/materialized-views/cascading-materialized-views) の使い方をステップごとに説明したガイドはこちらです。
</Tip>

materialized view は、対応する [SELECT](/ja/reference/statements/select/index) クエリで変換されたデータを格納します。

`TO [db].[table]` を指定せずに materialized view を作成する場合は、データを格納するためのテーブルエンジンである `ENGINE` を指定する必要があります。

`TO [db].[table]` を指定して materialized view を作成する場合は、`POPULATE` を使用して既存のソースデータからターゲットテーブルをバックフィルすることもできます (ターゲットテーブルにすでにデータが含まれている場合、バックフィルされた行は追加されます) 。`POPULATE` は `REFRESH` と併用できません。[リフレッシャブルmaterialized view](#refreshable-materialized-view) は最初のリフレッシュでデータが補完されるため、`POPULATE` を使用すると初期データが二重にロードされます (代わりに、最初のリフレッシュをスキップするには `EMPTY` を使用してください) 。

materialized view は次のように実装されています。`SELECT` で指定されたテーブルにデータが挿入されると、その挿入データの一部がこの `SELECT` クエリによって変換され、その結果がビューに挿入されます。

<Note>
  ClickHouse の materialized VIEW は、宛先テーブルへの挿入時にカラム順ではなく **カラム名** を使用します。`SELECT` クエリの結果に一部のカラム名が含まれていない場合、ClickHouse はそのカラムが [Nullable](/ja/reference/data-types/nullable) でなくてもデフォルト値を使用します。安全策として、Materialized VIEWs を使用する際はすべてのカラムに別名を付けることを推奨します。

  ClickHouse の materialized VIEW は、insert trigger に近い形で実装されています。VIEW クエリに集約が含まれている場合、それは新たに挿入されたデータのバッチに対してのみ適用されます。ソーステーブル の既存データに対する変更 (update、delete、drop partition など) は、materialized VIEW には反映されません。

  ClickHouse の materialized VIEW は、エラー発生時の動作が決定論的ではありません。つまり、すでに書き込まれた blocks は宛先テーブルに保持されますが、エラー発生後の blocks は保持されません。

  デフォルトでは、いずれかの VIEW への書き込みで例外が発生すると、`INSERT` クエリは失敗します。その時点までに block がすでに ソーステーブル に到達しているかどうかは保証されません。これは VIEW 側のエラーではなく、insert pipeline のタイミングに依存します。失敗した `INSERT` は、挿入の重複排除 (`insert_deduplicate`、`deduplicate_blocks_in_dependent_materialized_views`) を有効にして再試行し、ソーステーブル とそれに依存するすべての VIEWs への exactly-once 配信を実現してください。

  `INSERT` クエリに `materialized_views_ignore_errors=true` を設定しても、変わるのはエラー報告だけです。各 VIEW のエラーは警告としてログに記録され、`INSERT` クエリ自体は成功します。失敗した VIEW の宛先への配信は部分的になります。つまり、例外発生前に処理された blocks は保持され、失敗した block とそれ以降の blocks はその VIEW から破棄されます。その宛先の下流にある VIEWs には到達した blocks だけが渡されるため、それらへの配信も部分的になります。例外を発生させなかった sibling VIEW (およびその下流チェーン) には完全に書き込まれ、ソーステーブル にも通常どおり書き込まれます。`INSERT` は成功として報告されるため、クライアントには失敗のシグナルが返らず、自動的な再試行もトリガーされません。この設定は、VIEW 側の問題によって ソーステーブル への書き込みを妨げてはならない場合にのみ使用してください (たとえば `system.*_log` tables) 。

  `materialized_views_ignore_errors` は、`system.*_log` tables ではデフォルトで `true` です。
</Note>

`POPULATE` を指定すると、既存のソーステーブルのデータは、作成時に VIEW に挿入されます。そうでない場合、VIEW に含まれるのは、VIEW の作成後にソーステーブルに挿入されたデータのみです。

通常の `CREATE MATERIALIZED VIEW` では、`POPULATE` はデフォルトで **アトミック** です (設定 `materialized_views_populate_atomically = 1`) 。ソーステーブルへの新規挿入に VIEW がサブスクライブされ、既存データのスナップショットが、ソーステーブルに対する短時間の排他ロックのもとで同時に取得されます。これにより、データ投入と同時に挿入されたすべての行は、欠落も重複もなく VIEW に **正確に一度だけ** 配信されます。その後、 (長時間実行される可能性がある) データ投入では、ロックを保持せずに固定されたスナップショットを読み取ります。

これはローカルな挿入パスのアトミック性です。排他ロックは、**同じサーバー上で**このソーステーブルのストレージロックを取得する挿入とのみ直列化されるため、exactly-once 保証の対象はこのサーバー経由で到着する挿入です。これはクラスター全体の保証ではありません。データ投入と同時に `ReplicatedMergeTree` ソースの別のレプリカに挿入された行や、分散書き込みパス (たとえば `Distributed` table への書き込み、または `ON CLUSTER` 経由) で挿入された行は、この境界の対象外であり、欠落または重複する可能性があります。

データ投入が失敗した場合 (たとえば、負荷の高いソーステーブルに対する排他ロックを `lock_acquire_timeout` 内に取得できない場合や、実行中に VIEW の `SELECT` が例外を発生させた場合) 、作成直後の VIEW は削除され、`CREATE` クエリは失敗します。作成されたものは何も残らないため、単純に再試行できます。`TO [db].[table]` 形式では、このロールバックで削除されるのは VIEW のみであり、既存のターゲットテーブルが削除されることはありません。ただし、失敗したデータ投入ですでにターゲットに挿入された行は、当該テーブルへの `INSERT ... SELECT` が失敗した後と同様に残るため、`CREATE` を再試行すると再度挿入されます。バックフィルを正確に行う必要がある場合は、切り詰めたターゲットテーブルまたは新しいターゲットテーブルに再試行するか、`ReplacingMergeTree` のような重複排除エンジンを使用してください。

<Note>
  アトミック性を確保するには、ソーステーブルが固定された特定時点のスナップショットの読み取りをサポートしている必要があります。対象は `MergeTree` ファミリーと `Memory` です。それ以外のソース (VIEW、`Distributed`、`Merge`、`Buffer`、`Log` ファミリー、または `Atomic` database に含まれない table) では、データ投入は従来の非アトミックな動作にフォールバックします (server log に記録されます) 。既存データは個別の非協調スナップショットで読み取られるため、データ投入中に挿入された行が欠落または重複する可能性があります。その場合、正確なデータが必要であれば VIEW を作成し、個別に `INSERT ... SELECT` を実行してください。`materialized_views_populate_atomically = 0` を設定すると、すべてのソースでこの従来の動作が強制されます。

  アトミックなデータ投入は、通常の `CREATE MATERIALIZED VIEW` にのみ適用されます。`CREATE OR REPLACE` / `REPLACE MATERIALIZED VIEW ... POPULATE` は常に従来の非アトミックなデータ投入を使用します。

  `POPULATE` は `Replicated` databases ではサポートされていません (`database_replicated_allow_heavy_create` を使用すると上書きできます) 。また、ClickHouse Cloud でもサポートされていません。この上書きによって有効にした場合、データ投入は常に従来の非アトミックなものになります。失敗したデータ投入をすべてのレプリカで一貫してロールバックすることはできないためです。
</Note>

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

materialized VIEW が `TO [db.]name` 構文を使用している場合は、その VIEW を `DETACH` し、ターゲットテーブルに対して `ALTER` を実行したあとで、先ほどデタッチした (`DETACH`) VIEW を `ATTACH` できます。

VIEW は通常の table と同じように見えます。たとえば、`SHOW TABLES` クエリの結果にも表示されます。

VIEW を削除するには、[DROP VIEW](/ja/reference/statements/drop#drop-view) を使用します。ただし、`DROP TABLE` も VIEW に対して機能します。

## SQL security

`DEFINER` と `SQL SECURITY` を使うと、ビューの基になるクエリを実行する際に、どの ClickHouse ユーザーを使用するかを指定できます。
`SQL SECURITY` には、`DEFINER`、`INVOKER`、`NONE` の 3 つの有効な値があります。`DEFINER` 句では、既存の任意のユーザー、または `CURRENT_USER` を指定できます。

次の表は、ビューから読み取るために、どのユーザーにどの権限が必要かを示しています。
なお、SQL security オプションにかかわらず、どの場合でもビューを読み取るには `GRANT SELECT ON <view>` が引き続き必要です。

| SQL security option | View | Materialized View |
| - | - | - |
| `DEFINER alice` | `alice` は、ビューのソーステーブルに対する `SELECT` 権限を持っている必要があります。 | `alice` は、ビューのソーステーブルに対する `SELECT` 権限と、ビューのターゲットテーブルに対する `INSERT` 権限を持っている必要があります。 |
| `INVOKER` | ユーザーは、ビューのソーステーブルに対する `SELECT` 権限を持っている必要があります。 | materialized views には `SQL SECURITY INVOKER` を指定できません。 |
| `NONE` | - | - |

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

`DEFINER`/`SQL SECURITY` が指定されていない場合、結果は [`ignore_empty_sql_security_in_create_view_query`](/ja/reference/settings/server-settings/settings/other#ignore_empty_sql_security_in_create_view_query) サーバー設定によって異なります。

デフォルト値の `true` では、クエリは記述どおりに保存され、ビューには空の SQL security タイプが設定されます。通常のビューは呼び出し元の権限で実行され、ターゲットテーブルが明示的に指定された materialized view では、そのターゲットテーブルに対するアクセスチェックがスキップされます。つまり、ソーステーブルへの挿入にはターゲットテーブルに対する `INSERT` 権限は不要であり、ビューからの読み取りにはそのターゲットテーブルに対する `SELECT` 権限は不要です。

`false` では、作成時に次のデフォルト値がビュー定義に書き込まれます。

* `SQL SECURITY`: 通常のビューでは `INVOKER` ([`default_normal_view_sql_security`](/ja/reference/settings/session-settings/default#default_normal_view_sql_security) で設定可能) 、materialized view では `DEFINER` ([`default_materialized_view_sql_security`](/ja/reference/settings/session-settings/default#default_materialized_view_sql_security) で設定可能)
* `DEFINER`: `CURRENT_USER` ([`default_view_definer`](/ja/reference/settings/session-settings/default#default_view_definer) で設定可能)

リフレッシャブルmaterialized view には、設定にかかわらず常にこれらのデフォルト値が設定されます。

ビューは、アタッチ時またはサーバー起動時の再読み込み時に、保存されている定義の SQL security タイプを維持します。そのため、`DEFINER`/`SQL SECURITY` なしで保存されたビューは、空の SQL security タイプを維持します。

既存のビューの SQL security を変更するには、次を使用します。

```sql theme={null}
ALTER TABLE MODIFY SQL SECURITY { DEFINER | INVOKER | NONE } [DEFINER = { user | CURRENT_USER }]
```

### 例

```sql theme={null}
CREATE VIEW test_view
DEFINER = alice SQL SECURITY DEFINER
AS SELECT ...
```

```sql theme={null}
CREATE VIEW test_view
SQL SECURITY INVOKER
AS SELECT ...
```

## Live View

<DeprecatedBadge />

この機能は非推奨であり、今後削除される予定です。

参考までに、旧ドキュメントは[こちら](https://pastila.nl/?00f32652/fdf07272a7b54bda7e13b919264e449f.md)にあります。

## リフレッシャブルmaterialized view

```sql theme={null}
CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
REFRESH [EVERY|AFTER interval [OFFSET interval]]
[RANDOMIZE FOR interval]
[DEPENDS ON [db.]name [, [db.]name [, ...]]]
[SETTINGS name = value [, name = value [, ...]]]
[APPEND [INCREMENTAL]]
[TO[db.]name] [(columns)] [ENGINE = engine]
[EMPTY]
[DEFINER = { user | CURRENT_USER }] [SQL SECURITY { DEFINER | NONE }]
AS SELECT ...
[COMMENT 'comment']
```

ここで、`interval` は単純なインターバルの列です。

```sql theme={null}
number SECOND|MINUTE|HOUR|DAY|WEEK|MONTH|YEAR
```

`REFRESH` clause では、`EVERY`、`AFTER`、`DEPENDS ON` の少なくとも 1 つを指定する必要があります。これらを 1 つも指定しない単独の `REFRESH` は拒否されます。`EVERY`/`AFTER` を伴わない `REFRESH DEPENDS ON ...` は、`REFRESH AFTER 0 SECOND DEPENDS ON ...` の省略形です。詳細は以下の [リフレッシュの依存関係](#refresh-dependencies) を参照してください。

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

* `APPEND` が指定されている場合、各リフレッシュでは既存の行を削除せずにテーブルへ行を挿入します。この insert は、通常の `INSERT INTO ... SELECT` クエリと同様にアトミックではありません。
* `APPEND INCREMENTAL` が指定されている場合、各リフレッシュでは前回のリフレッシュ以降にソーステーブルへコミットされた行のみを対象にクエリを実行し、その結果を追加します。
* それ以外の場合、各リフレッシュでテーブルの以前の内容はアトミックに置き換えられます。

通常の、リフレッシュ機能のない materialized view との違い:

* insert trigger はありません。`SELECT` で指定したテーブルに新しいデータが挿入されても、そのデータがリフレッシャブルmaterialized view に自動的に反映されることは *ありません*。代わりに、データの挿入は定期実行または手動実行のリフレッシュ時にのみ行われます。
* `SELECT` クエリには制約がありません。テーブル関数 (例: `url()`) 、ビュー、UNION、JOIN はいずれも使用できます。唯一の例外は `APPEND INCREMENTAL` で、`enable_block_number_column = 1` および `enable_block_offset_column = 1` を設定した単一のプレーンな `MergeTree` ソーステーブルが必要であり、`JOIN`、`UNION`、サブクエリ、ビュー、テーブル関数は使用できません。

<Note>
  クエリの `REFRESH ... SETTINGS` 部分で指定する設定はリフレッシュ設定 (例: `refresh_retries`) であり、通常の設定 (例: `max_threads`) とは異なります。通常の設定は、クエリ末尾の `SETTINGS` で指定できます。
</Note>

### リフレッシュ スケジュール

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

```sql theme={null}
REFRESH EVERY 1 DAY -- every day, at midnight (UTC)
REFRESH EVERY 1 MONTH -- on 1st day of every month, at midnight
REFRESH EVERY 1 MONTH OFFSET 5 DAY 2 HOUR -- on 6th day of every month, at 2:00 am
REFRESH EVERY 2 WEEK OFFSET 5 DAY 15 HOUR 10 MINUTE -- every other Saturday, at 3:10 pm
REFRESH EVERY 30 MINUTE -- at 00:00, 00:30, 01:00, 01:30, etc
REFRESH AFTER 30 MINUTE -- 30 minutes after the previous refresh completes, no alignment with time of day
-- REFRESH AFTER 1 HOUR OFFSET 1 MINUTE -- syntax error, OFFSET is not allowed with AFTER
REFRESH EVERY 1 WEEK 2 DAYS -- every 9 days, not on any particular day of the week or month;
                            -- specifically, when day number (since 1969-12-29) is divisible by 9
REFRESH EVERY 5 MONTHS -- every 5 months, different months each year (as 12 is not divisible by 5);
                       -- specifically, when month number (since 1970-01) is divisible by 5
```

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

```sql theme={null}
REFRESH EVERY 1 DAY OFFSET 2 HOUR RANDOMIZE FOR 1 HOUR -- every day at random time between 01:30 and 02:30
```

特定のビューでは、同時に実行できる refresh は最大 1 つまでです。たとえば、`REFRESH EVERY 1 MINUTE` を設定したビューの refresh に 2 分かかる場合、実際の refresh 間隔は 2 分になります。その後、処理が速くなって 10 秒で refresh できるようになれば、再び 1 分ごとの refresh に戻ります。 (つまり、実行されなかった refresh の遅れを取り戻すために 10 秒ごとに refresh されることはありません。そのような未実行分の backlog は存在しません。)

通常、最初の refresh は materialized view の作成直後に開始されます。前回の refresh からの経過時間は無限大であるため、どのスケジュールでも「今すぐ refresh すべき時刻」と判断されるからです。`EMPTY` が指定されている場合、この初回の refresh はスキップされ、最初の refresh は次にスケジュールされた時刻に実行されます。たとえば `EVERY 1 HOUR` では、最初の refresh は現在の時刻のちょうど1時間の区切りで実行されます。

### Replicated DB 内で

リフレッシャブルmaterialized view が [Replicated database](/ja/reference/engines/database-engines/replicated) 内にある場合、各レプリカは相互に協調し、スケジュールされた時刻ごとに 1 つのレプリカだけがリフレッシュを実行します。リフレッシュで生成されたデータをすべてのレプリカが参照できるようにするため、[ReplicatedMergeTree](/ja/reference/engines/table-engines/mergetree-family/replication) テーブルエンジンが必要です。

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

`APPEND` 以外のモードでは、協調されたリフレッシュのみがサポートされます。協調なしで行うには、`Atomic` データベースと `CREATE ... ON CLUSTER` クエリを使用して、すべてのレプリカにリフレッシャブルmaterialized view を作成してください。

協調は Keeper を通じて行われます。znode path は [default\_replica\_path](/ja/reference/settings/server-settings/settings/default-replica#default_replica_path) サーバー設定によって決まります。

### リフレッシュの依存関係

`DEPENDS ON` は、異なるテーブルのリフレッシュを同期します:

```sql theme={null}
CREATE MATERIALIZED VIEW dependent REFRESH EVERY 1 HOUR DEPENDS ON dependency [...]
```

依存ビューのリフレッシュは、依存先のすべてのビューのリフレッシュが完了してから開始されます。

別のビューのリフレッシュ直後にリフレッシュするには:

```sql theme={null}
CREATE MATERIALIZED VIEW dependent REFRESH AFTER 0 SECOND DEPENDS ON dependency [...]
```

あるいは、次のようにも書けます:

```sql theme={null}
CREATE MATERIALIZED VIEW dependent REFRESH DEPENDS ON dependency [...]
```

<Note>
  `DEPENDS ON` は、リフレッシャブルmaterialized view 間でのみ機能します。特に、依存先のビューが `TO <table>` を使用している場合は、テーブル名ではなくビュー名を使用してください。`DEPENDS ON` のリストに通常のテーブルやリフレッシャブルでないビューが含まれている場合、またはタイプミスがある場合、そのビューはリフレッシュされず、`system.view_refreshes` に状態 `MissingDependencies` と表示されます。依存関係は `ALTER` を使用して変更または削除できます。詳しくは [リフレッシュパラメータの変更](#changing-refresh-parameters) を参照してください。
</Note>

#### 伝播レイテンシを一定に保つための `DEPENDS ON` の使用

両方のビューが同じ周期で `REFRESH EVERY` を使用している場合、依存関係は各時間スロットに適用されます。

たとえば、ビュー X と Y がどちらも `REFRESH EVERY 1 HOUR` を使用し、Y が X の出力テーブルを読み取るとします。依存関係がない場合、Y は通常、前の時間のリフレッシュで生成された X のデータを参照します。`DEPENDS ON X` を使用すると、Y の 11:00 のリフレッシュは、X の 11:00 のリフレッシュが完了した後にのみ開始されます。

```text theme={null}
           10:00            11:00            12:00
           │                │                │
  X:        [run]┐           [run]┐           [run]┐
                 │                │                │
  Y:             └►[run]          └►[run]          └►[run]
```

依存対象と依存側は、リフレッシュの実行時間がリフレッシュ間隔より長い場合、それぞれ独立してタイムスロットをスキップすることがあります。依存側が依存対象の各リフレッシュに対してちょうど1回ずつリフレッシュされる保証はありません。

```text theme={null}
           10:00          11:00          12:00          13:00
           │              │              │              |
  X:        [run]┐         [run]┐         [run]┐         [run]┐
                 │              └────┐    (Y skips 12:00)     └───┐
  Y:             └►[10:00 ru------un]└►[11:00 ru---------------un]└►[13:00 run]
```

#### バッチ単位のストリーム処理での DEPENDS ON の使用

`REFRESH EVERY` を使用しない場合、依存するビュー X は、X の前回のリフレッシュ以降に、そのすべての依存関係が少なくとも 1 回リフレッシュされていればリフレッシュされます。`REFRESH AFTER T` は遅延を追加するもので、依存先は依存元のリフレッシュ完了から T 時間後にリフレッシュを開始します。

循環依存は許可されており、有用でもあります。次のリフレッシャブルmaterialized view のグラフを考えてみましょう。

1. X はある stream から行の batch を取り出し、それをテーブルに格納します。
2. 次に、Y と Z はどちらもそのテーブルを読み取り、異なる集計を行って、結果を別のテーブルに追記します。
3. batch の処理が完了すると、X は次の batch を取り出し、この cycle が繰り返されます。

```text theme={null}
            source
               │
               ▼
          ┌─────────┐
     ┌───►│    X    │◄───┐
     │    └──┬───┬──┘    │
  DEPENDS    │   │    DEPENDS
    ON       ▼   ▼      ON
     │      ┌─┐ ┌─┐      │
     └──────┤Y│ │Z├──────┘
            └─┘ └─┘
```

全体の例:

```sql theme={null}
CREATE TABLE current_batch (t UInt64, v Int64) ENGINE ReplicatedMergeTree ORDER BY t;
CREATE TABLE batch_log (max_t UInt64, n Int64, v_sum Int64, processed_at DateTime64) ENGINE ReplicatedMergeTree ORDER BY max_t;
CREATE TABLE stats (h UInt64, n UInt64) ENGINE ReplicatedSummingMergeTree ORDER BY h;

-- (system.numbers stands in for a data source with monotonically increasing timestamps or sequence numbers)
CREATE MATERIALIZED VIEW current_batch_v REFRESH EVERY 10 SECOND DEPENDS ON batch_log_v, stats_v TO current_batch AS SELECT number as t, number * 10 as v FROM system.numbers WHERE number > (SELECT max(max_t) FROM batch_log) LIMIT 100;

CREATE MATERIALIZED VIEW batch_log_v REFRESH DEPENDS ON current_batch_v APPEND TO batch_log AS SELECT max(t) as max_t, count() as n, sum(v) as v_sum, now64() as processed_at FROM current_batch;

CREATE MATERIALIZED VIEW stats_v REFRESH DEPENDS ON current_batch_v APPEND TO stats AS SELECT cityHash64(v) % 20 as h, count() as n FROM current_batch GROUP BY h;

-- Must trigger initial refresh manually.
SYSTEM REFRESH VIEW current_batch_v;
```

より長いチェーンでも機能します。

これは、リフレッシュの協調が有効になっている場合、つまりビューが Replicated または Shared データベースにある場合にのみ、うまく機能します。協調がないと、サーバーの再起動でその連鎖が途切れるため、ビューの作成後に一度だけではなく、再起動のたびに手動で `SYSTEM REFRESH VIEW` を実行する必要があります。

### リフレッシュ設定

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

* `refresh_retries` - リフレッシュクエリが例外で失敗した場合に、再試行する回数を指定します。すべての再試行が失敗した場合は、次にスケジュールされているリフレッシュ時刻までスキップします。0 は再試行なし、-1 は無制限の再試行を意味します。デフォルト: 2。
* `refresh_retry_initial_backoff_ms` - `refresh_retries` が 0 でない場合の、最初の再試行までの待機時間です。以降の再試行では、待機時間が回ごとに 2 倍になり、最大で `refresh_retry_max_backoff_ms` まで増加します。デフォルト: 100 ms。
* `refresh_retry_max_backoff_ms` - リフレッシュ試行の間隔が指数的に増加する際の上限です。デフォルト: 60000 ms (1 分) 。
* `all_replicas` - `APPEND` を使用する [Replicated database](/ja/reference/engines/database-engines/replicated) で、すべてのレプリカが独立してリフレッシュするか、スケジュール時刻ごとに 1 つのレプリカだけがリフレッシュするかを制御します。ビューの作成後は変更できません。デフォルト: `false`。

### リフレッシュパラメータの変更

既存のリフレッシャブルmaterialized viewのリフレッシュパラメータは、[`ALTER TABLE ... MODIFY REFRESH`](/ja/reference/statements/alter/view#alter-table--modify-refresh-statement)を使って変更します。

```sql theme={null}
ALTER TABLE [db.]name MODIFY REFRESH EVERY|AFTER ... [RANDOMIZE FOR ...] [DEPENDS ON ...] [SETTINGS ...]
```

スケジュール (`EVERY` または `AFTER`) の指定は必須です。このステートメントでは、リフレッシュに関するすべてのパラメーター (スケジュール、`RANDOMIZE FOR`、`DEPENDS ON`、およびリフレッシュ設定) が、指定した内容で常に丸ごと置き換えられます。省略した項目は、設定であればデフォルト値に戻され、依存関係やランダム化であれば削除されます。

<Note>
  * リフレッシュ設定のみを変更するには (例: `refresh_retries`) 、現在のスケジュールを再度指定してください。

    ```sql theme={null}
    ALTER TABLE rmv MODIFY REFRESH EVERY 1 HOUR SETTINGS refresh_retries = 5;
    ```

  * `ALTER TABLE ... MODIFY SETTING refresh_retries = ...` は materialized view ではサポートされていません。必ず `MODIFY REFRESH` を使用してください。

  * リフレッシュモードの変更はサポートされていません。`APPEND` と `INCREMENTAL` は追加も削除もできません。

  * `all_replicas` 設定は作成後に変更できません。
</Note>

例:

```sql theme={null}
-- Change the schedule, drop existing settings and dependencies.
ALTER TABLE rmv MODIFY REFRESH EVERY 30 MINUTE;

-- Change the schedule and tune retry behavior.
ALTER TABLE rmv MODIFY REFRESH EVERY 30 MINUTE
SETTINGS refresh_retries = 5,
         refresh_retry_initial_backoff_ms = 500,
         refresh_retry_max_backoff_ms = 60000;

-- Keep the dependency while changing the period.
ALTER TABLE rmv MODIFY REFRESH EVERY 6 HOUR DEPENDS ON other_rmv;

-- Drop the dependency by omitting `DEPENDS ON`.
ALTER TABLE rmv MODIFY REFRESH EVERY 6 HOUR;
```

### その他の操作

すべてのリフレッシャブルmaterialized viewの状態は、テーブル[`system.view_refreshes`](/ja/reference/system-tables/view_refreshes)で確認できます。特に、リフレッシュの進行状況 (実行中の場合) 、前回および次回のリフレッシュ時刻、リフレッシュが失敗した場合の例外メッセージが含まれます。

手動でリフレッシュを停止、開始、トリガー、またはキャンセルするには、[`SYSTEM STOP|START|REFRESH|WAIT|CANCEL VIEW`](/ja/reference/statements/system#managing-refreshable-materialized-views)を使用します。

リフレッシュの完了を待機するには、[`SYSTEM WAIT VIEW`](/ja/reference/statements/system#wait-view)を使用します。特に、ビューの作成後に初回リフレッシュが完了するのを待つ際に便利です。

<Note>
  豆知識: リフレッシュクエリは、現在リフレッシュ中のビューから読み取ることができ、その際にはリフレッシュ前のバージョンのデータを参照します。つまり、Conway's Game of Life を実装できます: [https://pastila.nl/?00021a4b/d6156ff819c83d490ad2dcec05676865#O0LGWTO7maUQIA4AcGUtlA==](https://pastila.nl/?00021a4b/d6156ff819c83d490ad2dcec05676865#O0LGWTO7maUQIA4AcGUtlA==)
</Note>

## 関連コンテンツ

* ブログ: [ClickHouseで時系列データを扱う](https://clickhouse.com/blog/working-with-time-series-data-and-functions-ClickHouse)
* ブログ: [ClickHouseでオブザーバビリティソリューションを構築する - パート2 - トレース](https://clickhouse.com/blog/storing-traces-and-spans-open-telemetry-in-clickhouse)

## 一時ビュー

ClickHouse は、**一時ビュー**をサポートしており、次のような特性があります (該当する場合は一時テーブルと同様です) 。

* **セッション存続期間**
  一時ビューは現在のセッション中にのみ存在します。セッションが終了すると自動的に削除されます。

* **データベースなし**
  一時ビューをデータベース名で修飾することは**できません**。一時ビューはデータベースの外側 (セッションのネームスペース) に存在します。

* **レプリケートされない / ON CLUSTER なし**
  一時オブジェクトはセッションローカルであり、`ON CLUSTER` を付けて作成することは**できません**。

* **名前解決**
  一時オブジェクト (テーブルまたはビュー) が永続オブジェクトと同じ名前を持ち、クエリがデータベース名を**付けずに**その名前を参照した場合は、**一時**オブジェクトが使用されます。

* **論理オブジェクト (ストレージなし) **
  一時ビューが保持するのは `SELECT` テキストのみです (内部的には `View` ストレージを使用します) 。データは永続化されず、`INSERT` も受け付けません。

* **Engine 句**
  `ENGINE` を指定する必要は**ありません**。`ENGINE = View` として指定した場合も、無視されるか、同じ論理ビューとして扱われます。

* **セキュリティ / 権限**
  一時ビューを作成するには `CREATE TEMPORARY VIEW` 権限が必要です。この権限は `CREATE VIEW` によって暗黙的に付与されます。

* **SHOW CREATE**
  一時ビューの DDL を表示するには、`SHOW CREATE TEMPORARY VIEW view_name;` を使用します。

### 構文

```sql theme={null}
CREATE TEMPORARY VIEW [IF NOT EXISTS] view_name AS <select_query>
```

`OR REPLACE` は、一時テーブルとの整合性を保つため、一時ビューでは **サポートされていません**。一時ビューを「置き換える」必要がある場合は、いったん削除してから再作成してください。

### 例

一時ソーステーブルを作成し、その上に一時ビューを作成します。

```sql theme={null}
CREATE TEMPORARY TABLE t_src (id UInt32, val String);
INSERT INTO t_src VALUES (1, 'a'), (2, 'b');

CREATE TEMPORARY VIEW tview AS
SELECT id, upper(val) AS u
FROM t_src
WHERE id <= 2;

SELECT * FROM tview ORDER BY id;
```

DDLを表示します:

```sql theme={null}
SHOW CREATE TEMPORARY VIEW tview;
```

削除:

```sql theme={null}
DROP TEMPORARY VIEW IF EXISTS tview;  -- 一時ビューは TEMPORARY TABLE 構文でドロップします
```

### 使用不可 / 制限事項

* `CREATE OR REPLACE TEMPORARY VIEW ...` → **使用できません** (`DROP` + `CREATE` を使用してください) 。
* `CREATE TEMPORARY MATERIALIZED VIEW ...` → **使用できません**。
* `CREATE TEMPORARY VIEW db.view AS ...` → **使用できません** (データベース修飾子は指定できません) 。
* `CREATE TEMPORARY VIEW view ON CLUSTER 'name' AS ...` → **使用できません** (一時オブジェクトはセッションローカルです) 。
* `POPULATE`, `REFRESH`, `TO [db.table]`, 内部エンジン、および MV 固有の句は、一時ビューには **適用されません**。

### 分散クエリに関する注意事項

一時**ビュー**は単なる定義にすぎず、受け渡すデータはありません。一時**ビュー**が一時**テーブル** (たとえば `Memory`) を参照している場合、そのデータは一時テーブルと同様に、分散クエリの実行中にリモートサーバーへ転送されることがあります。

#### 例

```sql theme={null}
-- A session-scoped, in-memory table
CREATE TEMPORARY TABLE temp_ids (id UInt64) ENGINE = Memory;

INSERT INTO temp_ids VALUES (1), (5), (42);

-- A session-scoped view over the temp table (purely logical)
CREATE TEMPORARY VIEW v_ids AS
SELECT id FROM temp_ids;

-- Replace 'test' with your cluster name.
-- GLOBAL JOIN forces ClickHouse to *ship* the small join-side (temp_ids via v_ids)
-- to every remote server that executes the left side.
SELECT count()
FROM cluster('test', system.numbers) AS n
GLOBAL ANY INNER JOIN v_ids USING (id)
WHERE n.number < 100;

```
