ClickHouse/docs/ru/sql-reference/statements/create/view.md

254 lines
18 KiB
Markdown
Raw Normal View History

---
toc_priority: 37
toc_title: "\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435"
---
# CREATE VIEW {#create-view}
Создаёт представление. Представления бывают двух видов - обычные и материализованные (MATERIALIZED).
## Обычные представления {#normal}
``` sql
CREATE [OR REPLACE] VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] AS SELECT ...
```
2021-03-14 21:51:35 +00:00
Обычные представления не хранят никаких данных, они выполняют чтение данных из другой таблицы при каждом доступе. Другими словами, обычное представление — это не что иное, как сохраненный запрос. При чтении данных из представления этот сохраненный запрос используется как подзапрос в секции [FROM](../../../sql-reference/statements/select/from.md).
Для примера, пусть вы создали представление:
``` sql
CREATE VIEW view AS SELECT ...
```
и написали запрос:
``` sql
SELECT a, b, c FROM view
```
Этот запрос полностью эквивалентен использованию подзапроса:
``` sql
SELECT a, b, c FROM (SELECT ...)
```
## Материализованные представления {#materialized}
``` sql
CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...
```
Материализованные (MATERIALIZED) представления хранят данные, преобразованные соответствующим запросом [SELECT](../../../sql-reference/statements/select/index.md).
При создании материализованного представления без использования `TO [db].[table]`, нужно обязательно указать `ENGINE` - движок таблицы для хранения данных.
2021-03-14 21:51:35 +00:00
При создании материализованного представления с испольованием `TO [db].[table]`, нельзя указывать `POPULATE`.
Материализованное представление устроено следующим образом: при вставке данных в таблицу, указанную в SELECT-е, кусок вставляемых данных преобразуется этим запросом SELECT, и полученный результат вставляется в представление.
!!! important "Важно"
2021-03-14 21:51:35 +00:00
Материализованные представления в ClickHouse больше похожи на `after insert` триггеры. Если в запросе материализованного представления есть агрегирование, оно применяется только к вставляемому блоку записей. Любые изменения существующих данных исходной таблицы (например обновление, удаление, удаление раздела и т.д.) не изменяют материализованное представление.
Если указано `POPULATE`, то при создании представления, в него будут вставлены имеющиеся данные таблицы, как если бы был сделан запрос `CREATE TABLE ... AS SELECT ...` . Иначе, представление будет содержать только данные, вставляемые в таблицу после создания представления. Не рекомендуется использовать POPULATE, так как вставляемые в таблицу данные во время создания представления, не попадут в него.
Запрос `SELECT` может содержать `DISTINCT`, `GROUP BY`, `ORDER BY`, `LIMIT`… Следует иметь ввиду, что соответствующие преобразования будут выполняться независимо, на каждый блок вставляемых данных. Например, при наличии `GROUP BY`, данные будут агрегироваться при вставке, но только в рамках одной пачки вставляемых данных. Далее, данные не будут доагрегированы. Исключение - использование ENGINE, производящего агрегацию данных самостоятельно, например, `SummingMergeTree`.
Недоработано выполнение запросов `ALTER` над материализованными представлениями, поэтому они могут быть неудобными для использования. Если материализованное представление использует конструкцию `TO [db.]name`, то можно выполнить `DETACH` представления, `ALTER` для целевой таблицы и последующий `ATTACH` ранее отсоединенного (`DETACH`) представления.
2021-03-14 21:51:35 +00:00
Обратите внимание, что работа материализованного представления находится под влиянием настройки [optimize_on_insert](../../../operations/settings/settings.md#optimize-on-insert). Перед вставкой данных в таблицу происходит их слияние.
2021-02-06 09:43:48 +00:00
Представления выглядят так же, как обычные таблицы. Например, они перечисляются в результате запроса `SHOW TABLES`.
Отсутствует отдельный запрос для удаления представлений. Чтобы удалить представление, следует использовать `DROP TABLE`.
2021-03-14 21:51:35 +00:00
## Живые представления (экспериментальные) {#live-view}
!!! important "Важно"
Нововведение работает в тестовом режиме. Его использование может повлечь потерю совместимости в будущих версиях.
Включить их и запрос `WATCH` можно установкой `set allow_experimental_live_view = 1`.
```sql
CREATE LIVE VIEW [IF NOT EXISTS] [db.]table_name [WITH [TIMEOUT [value_in_sec] [AND]] [REFRESH [value_in_sec]]] AS SELECT ...
```
Живые представления хранят результат указанного запроса [SELECT](../../../sql-reference/statements/select/index.md) и обновляется сразу после изменения этого результата. Конечный результат запроса и промежуточные данные, из которых формируется результат, требуют наиболее производительной оперативной памяти для неоднократных запросов. Живые представления имеют возможность отправки push-уведомлений при изменении результата запроса `SELECT`. Для этого используйте запрос [WATCH](../../../sql-reference/statements/watch.md).
Изменение живого представления запускается вставкой данных в основную таблицу запроса.
Живые представления действуют схоже с запросами в рассредоточенных таблицах. Но вместо сборки отдельных результатов запросов с разных серверов, данные запросы объединяют результат из имеющихся данных с полученными новыми данными. Когда в запросе живого представления есть вложенный подзапрос, кешированный промежуточный результат будет храниться для подзапроса наибольшего уровня вложенности.
!!! info "Ограничения"
- [Табличные функции](../../../sql-reference/table-functions/index.md) не поддерживаются для базовой таблицы.
- Таблицы, не поддерживающие изменение с помощью запроса `INSERT`, такие как [Словари](../../../sql-reference/dictionaries/index.md) и [Системные таблицы](../../../operations/system-tables/index.md), а также [Нормальные представления](#normal) или [Материализованные представления](#materialized), не запускают обновление живого представления.
2021-03-14 21:51:35 +00:00
- Работают только запросы, сочетающие в себе частичные результаты из новых и старых данных. Живые представления не работают с запросами, требующими цельный набор данных для вычисления результата, и агрегациями с неизменяемым состоянием.
- Не работает для таблиц на движках Replicated или Distributed, вставка данных в которые происходит на разных узлах.
- Живое представление не обновляется, если используются несколько таблиц.
Используйте [WITH REFRESH](#live-view-with-refresh), чтобы принудительно обновлять живое представление с установленной периодичностью.
Для отслеживания изменений живого представления используйте запрос [WATCH](../../../sql-reference/statements/watch.md).
```sql
WATCH [db.]live_view
```
**Пример:**
```sql
CREATE TABLE mt (x Int8) Engine = MergeTree ORDER BY x;
CREATE LIVE VIEW lv AS SELECT sum(x) FROM mt;
```
Отслеживайте изменения живого представления таблицы при параллельной вставке данных в нее.
```sql
WATCH lv
```
```bash
┌─sum(x)─┬─_version─┐
│ 1 │ 1 │
└────────┴──────────┘
┌─sum(x)─┬─_version─┐
│ 2 │ 2 │
└────────┴──────────┘
┌─sum(x)─┬─_version─┐
│ 6 │ 3 │
└────────┴──────────┘
...
```
```sql
INSERT INTO mt VALUES (1);
INSERT INTO mt VALUES (2);
INSERT INTO mt VALUES (3);
```
Или используйте параметр [EVENTS](../../../sql-reference/statements/watch.md#events-clause) для получения списка изменений.
```sql
WATCH [db.]live_view EVENTS
```
**Пример:**
```sql
WATCH lv EVENTS
```
```bash
┌─version─┐
│ 1 │
└─────────┘
┌─version─┐
│ 2 │
└─────────┘
┌─version─┐
│ 3 │
└─────────┘
...
```
Используйте запрос [SELECT](../../../sql-reference/statements/select/index.md) для живого представления, как для любого другого представления. Если результат запроса кеширован, он будет возвращен немедленно, без обращения к исходным таблицам представления.
```sql
SELECT * FROM [db.]live_view WHERE ...
```
### Принудительное обновление {#live-view-alter-refresh}
You can force live view refresh using the `ALTER LIVE VIEW [db.]table_name REFRESH` statement.
Можно принудительно обновить живое представление, используя выражение `ALTER LIVE VIEW [db.]table_name REFRESH`.
### WITH TIMEOUT {#live-view-with-timeout}
Живое представление, созданное с параметром `WITH TIMEOUT`, будет автоматически удалено через определенное количество секунд с момента предыдущего запроса [WATCH](../../../sql-reference/statements/watch.md), примененного к данному живому представлению.
```sql
CREATE LIVE VIEW [db.]table_name WITH TIMEOUT [value_in_sec] AS SELECT ...
```
Если не был указано значение временного промежутка, используется значение `temporary_live_view_timeout`.
**Пример:**
```sql
CREATE TABLE mt (x Int8) Engine = MergeTree ORDER BY x;
CREATE LIVE VIEW lv WITH TIMEOUT 15 AS SELECT sum(x) FROM mt;
```
### WITH REFRESH {#live-view-with-refresh}
Живое представление, созданное с параметром `WITH REFRESH`, будет автоматически обновляться после определенного временного промежутка, прошедшего с последнего обновления.
```sql
CREATE LIVE VIEW [db.]table_name WITH REFRESH [value_in_sec] AS SELECT ...
```
Если значение временного промежутка не задано, используется значение `periodic_live_view_refresh`.
**Пример:**
```sql
CREATE LIVE VIEW lv WITH REFRESH 5 AS SELECT now();
WATCH lv
```
```bash
┌───────────────now()─┬─_version─┐
│ 2021-02-21 08:47:05 │ 1 │
└─────────────────────┴──────────┘
┌───────────────now()─┬─_version─┐
│ 2021-02-21 08:47:10 │ 2 │
└─────────────────────┴──────────┘
┌───────────────now()─┬─_version─┐
│ 2021-02-21 08:47:15 │ 3 │
└─────────────────────┴──────────┘
```
Можно сочетать параметры `WITH TIMEOUT` и `WITH REFRESH` с помощью `AND`.
```sql
CREATE LIVE VIEW [db.]table_name WITH TIMEOUT [value_in_sec] AND REFRESH [value_in_sec] AS SELECT ...
```
**Пример:**
```sql
CREATE LIVE VIEW lv WITH TIMEOUT 15 AND REFRESH 5 AS SELECT now();
```
По истечении 15 секунд, представление будет автоматически удалено, если нет активного запроса `WATCH`.
```sql
WATCH lv
```
```
Code: 60. DB::Exception: Received from localhost:9000. DB::Exception: Table default.lv doesn't exist..
```
### Использование
Наиболее вероятные применения живых представлений:
- Получение push-уведомлений с изменениями представления, без необходимости отправки запроса для отслеживания изменений.
- Кеширование результатов часто используемых запросов для их получения без задержки.
- Отслеживание изменений таблицы и запуск последующих запросов `SELECT`.
- Отслеживание показателей из системных таблиц с помощью периодических обновлений.
### Параметры {#live-view-settings}
Для управления поведением живых представлений можно использовать следующие параметры.
- `allow_experimental_live_view` - включить использование живых представлений. По умолчанию установлено `0`.
- `live_view_heartbeat_interval` - the heartbeat interval in seconds to indicate live query is alive. Default is `15` seconds.
- `live_view_heartbeat_interval` - периодичность индикации активности в секундах, по истечении которого представление «подаст признаки жизни». По умолчанию установлено `15`.
- `max_live_view_insert_blocks_before_refresh` - наибольшее число вставок, после которых запрос на формирование представления исполняется снова. По умолчанию количество вставок установлено `64`.
- `temporary_live_view_timeout` - interval after which live view with timeout is deleted. Default is `5` seconds.
- `temporary_live_view_timeout` - время в секундах, после которого представление удаляется. По умолчанию `5`.
- `periodic_live_view_refresh` - interval after which periodically refreshed live view is forced to refresh. Default is `60` seconds.
- `periodic_live_view_refresh` - время в секундах, по истечении которого живое представление с установленным автообновлением обновляется. По умолчанию `60`.
2021-02-06 09:48:53 +00:00
[Оригинальная статья](https://clickhouse.tech/docs/ru/sql-reference/statements/create/view) <!--hide-->