view.md 6.1 KB
Newer Older
A
Anna 已提交
1
---
2
toc_priority: 37
3
toc_title: "Представление"
A
Anna 已提交
4 5 6 7
---

# CREATE VIEW {#create-view}

8 9 10 11
Создаёт представление. Представления бывают двух видов - обычные и материализованные (MATERIALIZED).

## Обычные представления {#normal}

A
Anna 已提交
12
``` sql
13
CREATE [OR REPLACE] VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] AS SELECT ...
A
Anna 已提交
14 15
```

16
Обычные представления не хранят никаких данных, они выполняют чтение данных из другой таблицы при каждом доступе. Другими словами, обычное представление - это не что иное, как сохраненный запрос. При чтении данных из представления этот сохраненный запрос используется как подзапрос в секции [FROM](../../../sql-reference/statements/select/from.md).
A
Anna 已提交
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

Для примера, пусть вы создали представление:

``` sql
CREATE VIEW view AS SELECT ...
```

и написали запрос:

``` sql
SELECT a, b, c FROM view
```

Этот запрос полностью эквивалентен использованию подзапроса:

``` sql
SELECT a, b, c FROM (SELECT ...)
```

36
## Материализованные представления {#materialized}
A
Anna 已提交
37

38 39 40 41 42 43 44
``` 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` - движок таблицы для хранения данных.
A
Anna 已提交
45 46 47 48 49

При создании материализованного представления с испольованием `TO [db].[table]`, нельзя указывать `POPULATE`

Материализованное представление устроено следующим образом: при вставке данных в таблицу, указанную в SELECT-е, кусок вставляемых данных преобразуется этим запросом SELECT, и полученный результат вставляется в представление.

50 51 52 53
!!! important "Важно"
    Материализованные представлени в ClickHouse больше похожи на `after insert` триггеры. Если в запросе материализованного представления есть агрегирование, оно применяется только к вставляемому блоку записей. Любые изменения существующих данных исходной таблицы (например обновление, удаление, удаление раздела и т.д.) не изменяют материализованное представление.

Если указано `POPULATE`, то при создании представления, в него будут вставлены имеющиеся данные таблицы, как если бы был сделан запрос `CREATE TABLE ... AS SELECT ...` . Иначе, представление будет содержать только данные, вставляемые в таблицу после создания представления. Не рекомендуется использовать POPULATE, так как вставляемые в таблицу данные во время создания представления, не попадут в него.
A
Anna 已提交
54 55 56 57 58

Запрос `SELECT` может содержать `DISTINCT`, `GROUP BY`, `ORDER BY`, `LIMIT`… Следует иметь ввиду, что соответствующие преобразования будут выполняться независимо, на каждый блок вставляемых данных. Например, при наличии `GROUP BY`, данные будут агрегироваться при вставке, но только в рамках одной пачки вставляемых данных. Далее, данные не будут доагрегированы. Исключение - использование ENGINE, производящего агрегацию данных самостоятельно, например, `SummingMergeTree`.

Недоработано выполнение запросов `ALTER` над материализованными представлениями, поэтому они могут быть неудобными для использования. Если материализованное представление использует конструкцию `TO [db.]name`, то можно выполнить `DETACH` представления, `ALTER` для целевой таблицы и последующий `ATTACH` ранее отсоединенного (`DETACH`) представления.

G
gyuton 已提交
59
Обратите внимание, что работа материлизованного представления находится под влиянием настройки [optimize_on_insert](../../../operations/settings/settings.md#optimize-on-insert). Перед вставкой данных в таблицу происходит их слияние.
G
George 已提交
60
 
A
Anna 已提交
61 62 63 64
Представления выглядят так же, как обычные таблицы. Например, они перечисляются в результате запроса `SHOW TABLES`.

Отсутствует отдельный запрос для удаления представлений. Чтобы удалить представление, следует использовать `DROP TABLE`.