尚未崩坏 发表于 2024-12-9 00:08:11

ClickHouse 物化视图学习总结

物化视图

物化视图源表--基础数据源

创建源表,因为我们的目标涉及报告聚合数据而不是单条记录,所以我们可以剖析它,将信息通报给物化视图,并抛弃现实传入的数据。这符合我们的目标并节省了存储空间,因此我们将使用Null表引擎。
CREATE DATABASE IF NOT EXISTS analytics;

CREATE TABLE analytics.hourly_data
(
    `domain_name` String,
    `event_time` DateTime,
    `count_views` UInt64
)
ENGINE = Null;留意:可以在Null表上创建物化视图。因此,写入表的数据终极会影响视图,但原始原始数据仍将被抛弃
月度汇总表和物化视图

对于第一个物化视图,需要创建 Target 表(本例子中为analytics.monthly_aggregated_data),例中将按月份和域名存储视图的总和。
CREATE TABLE analytics.monthly_aggregated_data
(
    `domain_name` String,
    `month` Date,
    `sumCountViews` AggregateFunction(sum, UInt64)
)
ENGINE = AggregatingMergeTree
ORDER BY (domain_name, month);将转发Target表上数据的物化视图如下:
CREATE MATERIALIZED VIEW analytics.monthly_aggregated_data_mv
TO analytics.monthly_aggregated_data
AS
SELECT
    toDate(toStartOfMonth(event_time)) AS month,
    domain_name,
    sumState(count_views) AS sumCountViews
FROM analytics.hourly_data
GROUP BY domain_name, month;年度汇总表和物化视图

现在,创建第二个物化视图,该视图将链接到之前的目标表monthly_aggregated_data。
首先,创建一个新的目标表,该表将存储每个域名每年汇总的视图总和。
CREATE TABLE analytics.year_aggregated_data
(
    `domain_name` String,
    `year` UInt16,
    `sumCountViews` UInt64
)
ENGINE = SummingMergeTree()
ORDER BY (domain_name, year);然后创建物化视图,此步骤定义级联。FROM 语句将使用monthly_aggregated_data表,这意味着数据流将是:
1.数据到达hourly_data表。
2.ClickHouse会将收到的数据转发到第一个物化视图monthly_aggregated_data 表
3.末了,步骤2中吸收到的数据将被转发到 year_aggregated_data。
CREATE MATERIALIZED VIEW analytics.year_aggregated_data_mv
TO analytics.year_aggregated_data
AS
SELECT
    toYear(toStartOfYear(month)) AS year,
    domain_name,
    sumMerge(sumCountViews) as sumCountViews
FROM analytics.monthly_aggregated_data
GROUP BY domain_name, year;留意:
在使用物化视图时,一个常见的误解是数据是从表中读取的,这不是Materialized views的工作方式;转发的数据是插入的数据块,而不是表中的终极结果。
想象一下,在这个例子中,monthly_aggregated_data中使用的引擎是一个折叠合并树(CollapsingMergeTree),转发到第二个物化视图year_aggregated_data_mv 的数据将不是折叠表的终极结果,它将转发具有正如SELECT… GROUP BY中定义的字段的数据块。
如果末正在使用CollapsingMergeTree、ReplacingMergeTree,甚至SummingMergeTree,并且计划创建级联物化视图,则需要相识此处描述的限制。
采集数据

现在是时候通过插入一些数据来测试我们的级联物化视图了:
INSERT INTO analytics.hourly_data (domain_name, event_time, count_views)
VALUES ('clickhouse.com', '2019-01-01 10:00:00', 1),
       ('clickhouse.com', '2019-02-02 00:00:00', 2),
       ('clickhouse.com', '2019-02-01 00:00:00', 3),
       ('clickhouse.com', '2020-01-01 00:00:00', 6);查询analytics.hourly_data的内容,将查不到任何记录,因为表引擎为Null,但数据已被处置惩罚
SELECT * FROM analytics.hourly_data输出:
domain_name|event_time|count_views|
-----------+----------+-----------+结果

如果实验查询目标表的sumCountViews字段值,将看到字段值以二进制表示(在某些终端中),因为该值不是以数字的情势存储,而是以AggregateFunction类型存储的。要获得聚合的终极结果,应该使用-Merge后缀。
通过以下查询,sumCountViews字段值无法正常显示:
SELECT sumCountViews FROM analytics.monthly_aggregated_data输出:
sumCountViews|
-------------+
             |
             |
             |使用 Merge后缀获取 sumCountViews 值:
SELECT sumMerge(sumCountViews) as sumCountViews
FROM analytics.monthly_aggregated_data;输出:
sumCountViews|
-------------+
         12|在AggregatingMergeTree 中将AggregateFunction 定义为sum,因此可以使用sumMerge。当在AggregateFunction上使用函数avg时,则将使用avgMerge,以此类推。
SELECT month, domain_name, sumMerge(sumCountViews) as sumCountViews
FROM analytics.monthly_aggregated_data
GROUP BY domain_name, month输出:
month   |domain_name   |sumCountViews|
----------+--------------+-------------+
2020-01-01|clickhouse.com|            6|
2019-01-01|clickhouse.com|            1|
2019-02-01|clickhouse.com|            5|现在我们可以查看物化视图是否符合我们定义的目标。
现在已经将数据存储在目标表monthly_aggregated_data中,可以按月聚合每个域名的数据:
SELECT month, domain_name, sumMerge(sumCountViews) as sumCountViews
FROM analytics.monthly_aggregated_data
GROUP BY domain_name, month;输出:
month   |domain_name   |sumCountViews|
----------+--------------+-------------+
2020-01-01|clickhouse.com|            6|
2019-01-01|clickhouse.com|            1|
2019-02-01|clickhouse.com|            5|按年聚合每个域名的数据:
SELECT year, domain_name, sum(sumCountViews)
FROM analytics.year_aggregated_data
GROUP BY domain_name, year;输出:
year|domain_name   |sum(sumCountViews)|
----+--------------+------------------+
2019|clickhouse.com|               6|
2020|clickhouse.com|               6|组合多个源表来创建单个目标表

物化视图还可以用于将多个源表组合以到一个目标表中。这对于创建类似于 UNION ALL逻辑的物化视图非常有效。
首先,创建两个代表差别指标集的源表:
CREATE TABLE analytics.impressions
(
    `event_time` DateTime,
    `domain_name` String
) ENGINE = MergeTree ORDER BY (domain_name, event_time);

CREATE TABLE analytics.clicks
(
    `event_time` DateTime,
    `domain_name` String
) ENGINE = MergeTree ORDER BY (domain_name, event_time);然后使用组合的指标集创建 Target表:
CREATE TABLE analytics.daily_overview
(
    `on_date` Date,
    `domain_name` String,
    `impressions` SimpleAggregateFunction(sum, UInt64),
    `clicks` SimpleAggregateFunction(sum, UInt64)
) ENGINE = AggregatingMergeTree ORDER BY (on_date, domain_name);创建两个指向同一Target表的物化视图。不需要显式地包含缺少的列:
CREATE MATERIALIZED VIEW analytics.daily_impressions_mvTO analytics.daily_overviewAS                                                SELECT    toDate(event_time) AS on_date,    domain_name,    count() AS impressions,    0 clicks   --
页: [1]
查看完整版本: ClickHouse 物化视图学习总结