CREATE VIEW 

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

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

CREATE [OR REPLACE] VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] AS SELECT ...

Обычные представления не хранят никаких данных, они выполняют чтение данных из другой таблицы при каждом доступе. Другими словами, обычное представление — это не что иное, как сохраненный запрос. При чтении данных из представления этот сохраненный запрос используется как подзапрос в секции FROM.

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

CREATE VIEW view AS SELECT ...

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

SELECT a, b, c FROM view

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

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

Материализованные представления 

CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...

Материализованные (MATERIALIZED) представления хранят данные, преобразованные соответствующим запросом SELECT.

При создании материализованного представления без использования TO [db].[table], нужно обязательно указать ENGINE - движок таблицы для хранения данных.

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

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

Если указано 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. Перед вставкой данных в таблицу происходит их слияние.

Представления выглядят так же, как обычные таблицы. Например, они перечисляются в результате запроса SHOW TABLES.

Чтобы удалить представление, следует использовать DROP VIEW. Впрочем, DROP TABLE тоже работает для представлений.

LIVE-представления 

Представления LIVE VIEW являются экспериментальной возможностью. Их использование может повлечь потерю совместимости в будущих версиях.
Чтобы использовать LIVE VIEW и запросы WATCH, включите настройку allow_experimental_live_view.

CREATE LIVE VIEW [IF NOT EXISTS] [db.]table_name [WITH [TIMEOUT [value_in_sec] [AND]] [REFRESH [value_in_sec]]] AS SELECT ...

LIVE VIEW хранит результат запроса SELECT, указанного при создании, и обновляется сразу же при изменении этого результата. Конечный результат запроса и промежуточные данные, из которых формируется результат, хранятся в оперативной памяти, и это обеспечивает высокую скорость обработки для повторяющихся запросов. LIVE-представления могут отправлять push-уведомления при изменении результата исходного запроса SELECT. Для этого используйте запрос WATCH.

Изменение LIVE VIEW запускается при вставке данных в таблицу, указанную в исходном запросе SELECT.

LIVE-представления работают по тому же принципу, что и распределенные таблицы. Но вместо объединения отдельных частей данных с разных серверов, LIVE-представления объединяют уже имеющийся результат с новыми данными. Если в исходном запросе LIVE-представления есть вложенный подзапрос, его результаты не кешируются, в кеше хранится только результат основного запроса.

Отслеживание изменений 

Для отслеживания изменений LIVE-представления используйте запрос WATCH.

Пример:

CREATE TABLE mt (x Int8) Engine = MergeTree ORDER BY x;
CREATE LIVE VIEW lv AS SELECT sum(x) FROM mt;

Отслеживаем изменения LIVE-представления при вставке данных в исходную таблицу.

WATCH lv;
┌─sum(x)─┬─_version─┐
│      11 │
└────────┴──────────┘
┌─sum(x)─┬─_version─┐
│      22 │
└────────┴──────────┘
┌─sum(x)─┬─_version─┐
│      63 │
└────────┴──────────┘
...
INSERT INTO mt VALUES (1);
INSERT INTO mt VALUES (2);
INSERT INTO mt VALUES (3);

Для получения списка изменений используйте ключевое слово EVENTS.

WATCH lv EVENTS;
┌─version─┐
│       1 │
└─────────┘
┌─version─┐
│       2 │
└─────────┘
┌─version─┐
│       3 │
└─────────┘
...

Для работы с LIVE-представлениями, как и с любыми другими, можно использовать запросы SELECT. Если результат запроса кеширован, он будет возвращен немедленно, без обращения к исходным таблицам представления.

SELECT * FROM [db.]live_view WHERE ...

Принудительное обновление 

Чтобы принудительно обновить LIVE-представление, используйте запрос ALTER LIVE VIEW [db.]table_name REFRESH.

Секция WITH TIMEOUT 

LIVE-представление, созданное с параметром WITH TIMEOUT, будет автоматически удалено через определенное количество секунд с момента предыдущего запроса WATCH, примененного к данному LIVE-представлению.

CREATE LIVE VIEW [db.]table_name WITH TIMEOUT [value_in_sec] AS SELECT ...

Если временной промежуток не указан, используется значение настройки temporary_live_view_timeout.

Пример:

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-представление, созданное с параметром WITH REFRESH, будет автоматически обновляться через указанные промежутки времени, начиная с момента последнего обновления.

CREATE LIVE VIEW [db.]table_name WITH REFRESH [value_in_sec] AS SELECT ...

Если значение временного промежутка не задано, используется значение periodic_live_view_refresh.

Пример:

CREATE LIVE VIEW lv WITH REFRESH 5 AS SELECT now();
WATCH lv;
┌───────────────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.

CREATE LIVE VIEW [db.]table_name WITH TIMEOUT [value_in_sec] AND REFRESH [value_in_sec] AS SELECT ...

Пример:

CREATE LIVE VIEW lv WITH TIMEOUT 15 AND REFRESH 5 AS SELECT now();

По истечении 15 секунд представление будет автоматически удалено, если нет активного запроса WATCH.

WATCH lv;
Code: 60. DB::Exception: Received from localhost:9000. DB::Exception: Table default.lv doesn't exist.. 

Использование 

Наиболее частые случаи использования LIVE-VIEW:

  • Получение push-уведомлений об изменениях данных без дополнительных периодических запросов.
  • Кеширование результатов часто используемых запросов для получения их без задержки.
  • Отслеживание изменений таблицы для запуска других запросов SELECT.
  • Отслеживание показателей из системных таблиц с помощью периодических обновлений.

Оригинальная статья

Rating: 3 - 53 votes

Was this content helpful?
★★★☆☆