AggregatingMergeTree
该引擎继承自 MergeTree,更改数据部分合并的逻辑。ClickHouse 使用单个行替换具有相同主键(或更准确地说,具有相同 排序键)的所有行(在一个数据部分内),该行存储聚合函数状态的组合。
您可以将 AggregatingMergeTree
表用于增量数据聚合,包括聚合物化视图。
该引擎处理所有具有以下类型列
AggregateFunction
SimpleAggregateFunction
如果 AggregatingMergeTree
可以按数量级减少行数,则适合使用它。
创建表
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = AggregatingMergeTree()
[PARTITION BY expr]
[ORDER BY expr]
[SAMPLE BY expr]
[TTL expr]
[SETTINGS name=value, ...]
有关请求参数的说明,请参阅 请求说明。
查询子句
在创建 AggregatingMergeTree
表时,需要与创建 MergeTree
表时相同的 子句。
创建表的已弃用方法
在新项目中不要使用此方法,如果可能,请将旧项目切换到上面描述的方法。
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE [=] AggregatingMergeTree(date-column [, sampling_expression], (primary, key), index_granularity)
所有参数的含义与 MergeTree
中的相同。
SELECT 和 INSERT
要插入数据,请使用带有聚合 -State- 函数的 INSERT SELECT 查询。从 AggregatingMergeTree
表中选择数据时,请使用 GROUP BY
子句和与插入数据时相同的聚合函数,但使用 -Merge
后缀。
在 SELECT
查询的结果中,AggregateFunction
类型的值的对于所有 ClickHouse 输出格式都有特定于实现的二进制表示形式。如果将数据转储到例如 TabSeparated
格式中,使用 SELECT
查询,则可以使用 INSERT
查询加载回此转储。
聚合物化视图示例
以下示例假定您有一个名为 test
的数据库,因此请确保在它不存在时创建它。
CREATE DATABASE test;
我们将创建包含原始数据的表 test.visits
。
CREATE TABLE test.visits
(
StartDate DateTime64 NOT NULL,
CounterID UInt64,
Sign Nullable(Int32),
UserID Nullable(Int32)
) ENGINE = MergeTree ORDER BY (StartDate, CounterID);
接下来,我们需要创建一个 AggregatingMergeTree
表,该表将存储跟踪访问总次数和唯一用户数量的 AggregationFunction
。
监视 test.visits
表的 AggregatingMergeTree
物化视图,并使用 AggregateFunction
类型。
CREATE TABLE test.agg_visits (
StartDate DateTime64 NOT NULL,
CounterID UInt64,
Visits AggregateFunction(sum, Nullable(Int32)),
Users AggregateFunction(uniq, Nullable(Int32))
)
ENGINE = AggregatingMergeTree() ORDER BY (StartDate, CounterID);
然后让我们创建一个物化视图,它将 test.visits
中的数据填充到 test.agg_visits
中。
CREATE MATERIALIZED VIEW test.visits_mv TO test.agg_visits
AS SELECT
StartDate,
CounterID,
sumState(Sign) AS Visits,
uniqState(UserID) AS Users
FROM test.visits
GROUP BY StartDate, CounterID;
将数据插入 test.visits
表中。
INSERT INTO test.visits (StartDate, CounterID, Sign, UserID)
VALUES (1667446031000, 1, 3, 4), (1667446031000, 1, 6, 3);
数据同时插入到 test.visits
和 test.agg_visits
中。
要获取聚合数据,我们需要从物化视图 test.mv_visits
执行类似 SELECT ... GROUP BY ...
的查询。
SELECT
StartDate,
sumMerge(Visits) AS Visits,
uniqMerge(Users) AS Users
FROM test.agg_visits
GROUP BY StartDate
ORDER BY StartDate;
┌───────────────StartDate─┬─Visits─┬─Users─┐
│ 2022-11-03 03:27:11.000 │ 9 │ 2 │
└─────────────────────────┴────────┴───────┘
如果我们向 test.visits
添加另外几条记录,但这次我们将其中一条记录使用不同的时间戳,会怎么样呢?
INSERT INTO test.visits (StartDate, CounterID, Sign, UserID)
VALUES (1669446031000, 2, 5, 10), (1667446031000, 3, 7, 5);
如果我们再次运行 SELECT
查询,我们将看到以下输出。
┌───────────────StartDate─┬─Visits─┬─Users─┐
│ 2022-11-03 03:27:11.000 │ 16 │ 3 │
│ 2022-11-26 07:00:31.000 │ 5 │ 1 │
└─────────────────────────┴────────┴───────┘