ClickHouse/docs/ru/sql-reference/statements/create/view.md
michon470 55529c4dd6
Update docs/ru/sql-reference/statements/create/view.md
Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com>
2021-03-21 06:20:28 +03:00

254 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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 ...
```
Обычные представления не хранят никаких данных, они выполняют чтение данных из другой таблицы при каждом доступе. Другими словами, обычное представление — это не что иное, как сохраненный запрос. При чтении данных из представления этот сохраненный запрос используется как подзапрос в секции [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` - движок таблицы для хранения данных.
При создании материализованного представления с испольованием `TO [db].[table]`, нельзя указывать `POPULATE`.
Материализованное представление устроено следующим образом: при вставке данных в таблицу, указанную в SELECT-е, кусок вставляемых данных преобразуется этим запросом SELECT, и полученный результат вставляется в представление.
!!! important "Важно"
Материализованные представления в 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`) представления.
Обратите внимание, что работа материализованного представления находится под влиянием настройки [optimize_on_insert](../../../operations/settings/settings.md#optimize-on-insert). Перед вставкой данных в таблицу происходит их слияние.
Представления выглядят так же, как обычные таблицы. Например, они перечисляются в результате запроса `SHOW TABLES`.
Отсутствует отдельный запрос для удаления представлений. Чтобы удалить представление, следует использовать `DROP TABLE`.
## Живые представления (экспериментальные) {#live-view}
!!! important "Важно"
Представления `LIVE VIEW` являются экспериментальной возможностью. Их использование может повлечь потерю совместимости в будущих версиях.
Чтобы использовать `LIVE VIEW` и запросы `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), не запускают обновление живого представления.
- Работают только запросы, сочетающие в себе частичные результаты из новых и старых данных. Живые представления не работают с запросами, требующими цельный набор данных для вычисления результата, и агрегациями с неизменяемым состоянием.
- Не работает для таблиц на движках 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─┐
11
└────────┴──────────┘
┌─sum(x)─┬─_version─┐
22
└────────┴──────────┘
┌─sum(x)─┬─_version─┐
63
└────────┴──────────┘
...
```
```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`.
[Оригинальная статья](https://clickhouse.tech/docs/ru/sql-reference/statements/create/view) <!--hide-->