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

9.3 KiB
Raw Blame History

toc_priority toc_title
37 VIEW

CREATE VIEW

创建一个新视图。 有两种类型的视图:普通视图和物化视图。

Normal

语法:

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 ...)

Materialized

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

物化视图存储由相应的SELECT管理.

创建不带TO [db].[table]的物化视图时,必须指定ENGINE 用于存储数据的表引擎。

使用TO [db].[table] 创建物化视图时,不得使用POPULATE

一个物化视图的实现是这样的当向SELECT中指定的表插入数据时插入数据的一部分被这个SELECT查询转换结果插入到视图中。

!!! important "重要" ClickHouse 中的物化视图更像是插入触发器。 如果视图查询中有一些聚合,则它仅应用于一批新插入的数据。 对源表现有数据的任何更改(如更新、删除、删除分区等)都不会更改物化视图。

如果指定POPULATE,则在创建视图时将现有表数据插入到视图中,就像创建一个CREATE TABLE ... AS SELECT ...一样。 否则,查询仅包含创建视图后插入表中的数据。 我们不建议使用POPULATE因为在创建视图期间插入表中的数据不会插入其中。

SELECT 查询可以包含DISTINCTGROUP BYORDER BYLIMIT……请注意,相应的转换是在每个插入数据块上独立执行的。 例如,如果设置了GROUP BY,则在插入期间聚合数据,但仅在插入数据的单个数据包内。 数据不会被进一步聚合。 例外情况是使用独立执行数据聚合的ENGINE,例如SummingMergeTree

在物化视图上执行ALTER查询有局限性,因此可能不方便。 如果物化视图使用构造TO [db.]name,你可以DETACH视图,为目标表运行ALTER,然后ATTACH先前分离的(DETACH)视图。

请注意,物化视图受optimize_on_insert设置的影响。 在插入视图之前合并数据。

视图看起来与普通表相同。 例如它们列在1SHOW TABLES1查询的结果中。

删除视图,使用DROP VIEW. DROP TABLE也适用于视图。

Live View (实验性)

!!! important "重要" 这是一项实验性功能,可能会在未来版本中以向后不兼容的方式进行更改。 使用allow_experimental_live_view设置启用实时视图和WATCH查询的使用。 输入命令set allow_experimental_live_view = 1

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

实时视图存储相应SELECT查询的结果,并在查询结果更改时随时更新。 查询结果以及与新数据结合所需的部分结果存储在内存中,为重复查询提供更高的性能。当使用WATCH查询更改查询结果时,实时视图可以提供推送通知。

实时视图是通过插入到查询中指定的最里面的表来触发的。

实时视图的工作方式类似于分布式表中查询的工作方式。 但不是组合来自不同服务器的部分结果,而是将当前数据的部分结果与新数据的部分结果组合在一起。当实时视图查询包含子查询时,缓存的部分结果仅存储在最里面的子查询中。

!!! info "限制"

  • Table function不支持作为最里面的表.

  • 没有插入的表,例如dictionary, system table, normal view, materialized view不会触发实时视图。

  • 只有可以将旧数据的部分结果与新数据的部分结果结合起来的查询才有效。 实时视图不适用于需要完整数据集来计算最终结果或必须保留聚合状态的聚合的查询。

  • 不适用于在不同节点上执行插入的复制或分布式表。

  • 不能被多个表触发。

    WITH REFRESH强制定期更新实时视图,在某些情况下可以用作解决方法。

Monitoring Changes

您可以使用WATCH命令监视LIVE VIEW查询结果的变化

WATCH [db.]live_view

示例:

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

在对源表进行并行插入时观看实时视图。

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 [db.]live_view EVENTS;

示例:

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

你可以执行SELECT与任何常规视图或表格相同的方式查询实时视图。如果查询结果被缓存,它将立即返回结果而不在基础表上运行存储的查询。

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

Force Refresh

您可以使用ALTER LIVE VIEW [db.]table_name REFRESH语法.

WITH TIMEOUT条件

当使用WITH TIMEOUT子句创建实时视图时,WATCH观察实时视图的查询。

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条件

当使用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 │
└─────────────────────┴──────────┘

您可以使用AND子句组合WITH TIMEOUTWITH REFRESH子句。

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 does not exist..

Usage

实时视图表的最常见用途包括:

  • 为查询结果更改提供推送通知以避免轮询。
  • 缓存最频繁查询的结果以提供即时查询结果。
  • 监视表更改并触发后续选择查询。
  • 使用定期刷新从系统表中查看指标。

原始文章