问题描述
我正在研究 ClickHouse 的 VIEW、MATERIALIZED VIEW 和 LIVE VIEW。
实体化视图和实时视图在 official docs 中有很好的描述。
但是,对表描述的 VIEW 是有限的。 来自官方文档:
As an example,assume you’ve created a view:
CREATE VIEW view AS SELECT ...
and written a query:
SELECT a,b,c FROM view
但它没有指定我们正在执行 SELECT from 的表支持哪些表引擎。此外,没有使用示例。 能否提供一个VIEW的最低使用示例,并说明初始表支持哪些表引擎?
关于 VIEW 和 MATERIALIZED VIEW 类型之间的区别,我为 Oracle 找到了这个答案,看起来它也可以应用于 ClickHouse What is the difference between Views and Materialized Views in Oracle?。
示例 1
DROP TABLE IF EXISTS union;
create view union as select 1 as test union all select 2;
SELECT * FROM union ORDER BY test;
DETACH TABLE union;
ATTACH TABLE union;
SELECT * FROM union ORDER BY test;
DROP TABLE union;
示例 2:
DROP VIEW IF EXISTS test_view;
DROP TABLE IF EXISTS test_table;
CREATE TABLE test_table
(
f1 Int32,f2 Int32,pk Int32
)
ENGINE = MergeTree()
ORDER BY f1
PARTITION BY pk;
CREATE VIEW test_view AS
SELECT f1,f2
FROM test_table
WHERE pk = 2;
INSERT INTO test_table (f1,f2,pk) VALUES (1,1,1),(1,2),(2,2);
SELECT * FROM test_view ORDER BY f1,f2;
ALTER TABLE test_view DELETE WHERE pk = 2; --{serverError 48}
SELECT * FROM test_view ORDER BY f1,f2;
DROP VIEW IF EXISTS test_view;
DROP TABLE IF EXISTS test_table;
解决方法
视图只是一个保存的查询,仅此而已。
由于查询表时没有指定表引擎,所以不需要为视图指定引擎。您甚至可以组合多个表,每个表都有不同的表引擎。
因此,您可以为该查询创建一个视图,而不是一直发出很长的查询,这反过来又会添加一个抽象层来帮助您简化查询。
假设你有一个这样的表:
CREATE TABLE events(
device_id UInt64,dt DateTime,temp Float32
) Engine = MergeTree Order By (device_id,dt);
在您的应用程序中,您使用以下查询:
SELECT
device_id,toDate(dt) as day,count() as cnt
FROM events
GROUP BY device_id,day
如您所见,您正在根据为每个 device_id
生成的日期获取事件计数。
现在,如果您过于频繁地使用此信息,将这个查询放在另一个查询中会使它看起来非常复杂:
SELECT *
FROM event_detail ed
INNER JOIN (
SELECT
device_id,count() as cnt
FROM events
GROUP BY device_id,day
) daily_event_counts
ON ed.device_id = daily_event_counts.device_id
因此您为子查询创建一个视图,如下所示:
CREATE VIEW daily_event_counts AS
SELECT
device_id,day;
之后,编写查询会容易得多:
SELECT *
FROM event_detail ed
INNER JOIN daily_event_counts
ON ed.device_id = daily_event_counts.device_id
如您所见,它只是一个命名查询,仅此而已。