mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-06 23:54:10 +00:00
ee229a3980
Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com>
233 lines
16 KiB
Markdown
233 lines
16 KiB
Markdown
---
|
||
toc_priority: 37
|
||
toc_title: "Представление"
|
||
---
|
||
|
||
# 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 VIEW](../../../sql-reference/statements/drop.md#drop-view). Впрочем, `DROP TABLE` тоже работает для представлений.
|
||
|
||
## LIVE-представления {#live-view}
|
||
|
||
!!! important "Важно"
|
||
Представления `LIVE VIEW` являются экспериментальной возможностью. Их использование может повлечь потерю совместимости в будущих версиях.
|
||
Чтобы использовать `LIVE VIEW` и запросы `WATCH`, включите настройку [allow_experimental_live_view](../../../operations/settings/settings.md#allow-experimental-live-view).
|
||
|
||
```sql
|
||
CREATE LIVE VIEW [IF NOT EXISTS] [db.]table_name [WITH [TIMEOUT [value_in_sec] [AND]] [REFRESH [value_in_sec]]] AS SELECT ...
|
||
```
|
||
`LIVE VIEW` хранит результат запроса [SELECT](../../../sql-reference/statements/select/index.md), указанного при создании, и обновляется сразу же при изменении этого результата. Конечный результат запроса и промежуточные данные, из которых формируется результат, хранятся в оперативной памяти, и это обеспечивает высокую скорость обработки для повторяющихся запросов. LIVE-представления могут отправлять push-уведомления при изменении результата исходного запроса `SELECT`. Для этого используйте запрос [WATCH](../../../sql-reference/statements/watch.md).
|
||
|
||
Изменение `LIVE VIEW` запускается при вставке данных в таблицу, указанную в исходном запросе `SELECT`.
|
||
|
||
LIVE-представления работают по тому же принципу, что и распределенные таблицы. Но вместо объединения отдельных частей данных с разных серверов, LIVE-представления объединяют уже имеющийся результат с новыми данными. Если в исходном запросе LIVE-представления есть вложенный подзапрос, его результаты не кешируются, в кеше хранится только результат основного запроса.
|
||
|
||
!!! info "Ограничения"
|
||
- [Табличные функции](../../../sql-reference/table-functions/index.md) в основном запросе не поддерживаются.
|
||
- Таблицы, не поддерживающие изменение с помощью запроса `INSERT`, такие как [словари](../../../sql-reference/dictionaries/index.md) и [системные таблицы](../../../operations/system-tables/index.md), а также [нормальные представления](#normal) или [материализованные представления](#materialized), не запускают обновление LIVE-представления.
|
||
- В LIVE-представлениях могут использоваться только такие запросы, которые объединяют результаты по старым и новым данным. LIVE-представления не работают с запросами, требующими полного пересчета данных или агрегирования с сохранением состояния.
|
||
- `LIVE VIEW` не работает для реплицируемых и распределенных таблиц, добавление данных в которые происходит на разных узлах.
|
||
- `LIVE VIEW` не обновляется, если в исходном запросе используются несколько таблиц.
|
||
|
||
В случаях, когда `LIVE VIEW` не обновляется автоматически, чтобы обновлять его принудительно с заданной периодичностью, используйте [WITH REFRESH](#live-view-with-refresh).
|
||
|
||
### Отслеживание изменений {#live-view-monitoring}
|
||
|
||
Для отслеживания изменений LIVE-представления используйте запрос [WATCH](../../../sql-reference/statements/watch.md).
|
||
|
||
|
||
**Пример:**
|
||
|
||
```sql
|
||
CREATE TABLE mt (x Int8) Engine = MergeTree ORDER BY x;
|
||
CREATE LIVE VIEW lv AS SELECT sum(x) FROM mt;
|
||
```
|
||
Отслеживаем изменения LIVE-представления при вставке данных в исходную таблицу.
|
||
|
||
```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 lv EVENTS;
|
||
```
|
||
|
||
```bash
|
||
┌─version─┐
|
||
│ 1 │
|
||
└─────────┘
|
||
┌─version─┐
|
||
│ 2 │
|
||
└─────────┘
|
||
┌─version─┐
|
||
│ 3 │
|
||
└─────────┘
|
||
...
|
||
```
|
||
|
||
Для работы с LIVE-представлениями, как и с любыми другими, можно использовать запросы [SELECT](../../../sql-reference/statements/select/index.md). Если результат запроса кеширован, он будет возвращен немедленно, без обращения к исходным таблицам представления.
|
||
|
||
```sql
|
||
SELECT * FROM [db.]live_view WHERE ...
|
||
```
|
||
|
||
### Принудительное обновление {#live-view-alter-refresh}
|
||
|
||
Чтобы принудительно обновить LIVE-представление, используйте запрос `ALTER LIVE VIEW [db.]table_name REFRESH`.
|
||
|
||
### Секция WITH TIMEOUT {#live-view-with-timeout}
|
||
|
||
LIVE-представление, созданное с параметром `WITH TIMEOUT`, будет автоматически удалено через определенное количество секунд с момента предыдущего запроса [WATCH](../../../sql-reference/statements/watch.md), примененного к данному LIVE-представлению.
|
||
|
||
```sql
|
||
CREATE LIVE VIEW [db.]table_name WITH TIMEOUT [value_in_sec] AS SELECT ...
|
||
```
|
||
|
||
Если временной промежуток не указан, используется значение настройки [temporary_live_view_timeout](../../../operations/settings/settings.md#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}
|
||
|
||
LIVE-представление, созданное с параметром `WITH REFRESH`, будет автоматически обновляться через указанные промежутки времени, начиная с момента последнего обновления.
|
||
|
||
```sql
|
||
CREATE LIVE VIEW [db.]table_name WITH REFRESH [value_in_sec] AS SELECT ...
|
||
```
|
||
|
||
Если значение временного промежутка не задано, используется значение [periodic_live_view_refresh](../../../operations/settings/settings.md#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..
|
||
```
|
||
|
||
### Использование {#live-view-usage}
|
||
|
||
Наиболее частые случаи использования `LIVE-VIEW`:
|
||
|
||
- Получение push-уведомлений об изменениях данных без дополнительных периодических запросов.
|
||
- Кеширование результатов часто используемых запросов для получения их без задержки.
|
||
- Отслеживание изменений таблицы для запуска других запросов `SELECT`.
|
||
- Отслеживание показателей из системных таблиц с помощью периодических обновлений.
|
||
|
||
[Оригинальная статья](https://clickhouse.tech/docs/ru/sql-reference/statements/create/view) <!--hide-->
|