微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 ClickHouse 中的表格上查看

如何解决在 ClickHouse 中的表格上查看

我正在研究 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

如您所见,它只是一个命名查询,仅此而已。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。