clickhouse引擎--AggregatingMergeTree引擎

AggregatingMergeTree引擎

AggregatingMergeTree能够在合并分区的时候,按照预先定义的条件聚合数据,同时,根据预先定义的聚合函数计算数据并通过二进制的格式存入表内,将同一分组下的多行数据聚合成一行,既减少了数据行,又降低了后续聚合查询的开销,可以说AggregatingMergeTree是SummingMergeTree的升级版,它们许多设计思路是一致的,例如同时定义order by与primary key的原因和目的,但在使用方法上,两者存在明显差异,应该说AggregatingMergeTree的定义方式是MergeTree家族中最为特殊的一个。

AggregatingMergeTree没有任何额外的设置参数,在分区合并时,在每个数据分区内,会按照order by聚合,而使用何种聚合函数,以及针对哪些列字段计算,则是通过定义AggregateFunction数据类型实现的,在insert和select时,也有独特的写法和要求:写入时需要使用-State语法,查询时使用-Merge语法。

AggregateFunction[arg1,arg2]; 参数——聚合函数 参数——数据类型

sumMerge sumState

从聚合表中查询数据

--1)建立明细表
create table detail_table(
id UInt8,
ctime Date,
money UInt64
)engine=MergeTree()
partition by toDate(ctime)
order by id;

--2)插入明细数据
insert into detail_table values(1,2021-08-06,100);
insert into detail_table values(1,2021-08-06,100);
insert into detail_table values(2,2021-08-07,200);
insert into detail_table values(2,2021-08-07,200);

--3)建立预先聚合表
--注意:其中UserID一列的类型为:AggregateFunction(uniq,UInt64)
create table agg_table(
id UInt8,
ctime Date,
money AggregateFunction(sum,UInt64)
)engine=AggregatingMergeTree()
partition by toDate(ctime)
order by id;

--4)从明细表中读取数据,插入聚合表
--注意:子查询中使用的聚合函数为sumState,对应写入语法<agg>-state
insert into agg_tableselect id,ctime,sumState(money)from detail_tablegroup by id,ctime;


--不能使用普通insert语句向AggregatingMergeTree中插入数据
--本SQL会报错:cannot convert UInt64 to AggregateFunction(uniq,UInt64)insert into agg_table values(1,2020-08-06,1);

--5)从聚合表中查询
--注意:select中使用的聚合函数为sumMerge,对应于查询语法<agg>-Merge
--直接查查不到数据
select id,ctime,sumMerge(money) as statefrom agg_tablegroup by id,ctime;
┌─id─┬──────ctime─┬─state─┐
│  2 │ 2021-08-07 │   400 │
│  1 │ 2021-08-06 │   200 │
└────┴────────────┴───────┘

使用物化视图同步聚合数据

--建立明细表
create table orders(
uid UInt64,
money UInt64,
ctime Date,
Sign Int8
)engine=MergeTree
partition by ctime
order by uid;

--插入数据
insert into orders values(1,100,toDate(now()),1);
insert into orders values(1,100,toDate(now()),1);
insert into orders values(1,100,toDate(now()),1);
insert into orders values(2,200,toDate(now()),1);
insert into orders values(2,200,toDate(now()),1);
insert into orders values(2,200,toDate(now()),1);

--创建物化视图
--向物化视图中同步数据
create materialized view orders_agg_view
engine=AggregatingMergeTree()
partition by ctime
order by uid
populate
as select uid,ctime,sumState(money) as mm  --注意别名
from orders group by uid,ctime;

--查询物化视图数据
select uid,ctime,sumMerge(mm) from orders_agg_view group by uid,ctime;
┌─uid─┬──────ctime─┬─sumMerge(mm)─┐
│   1 │ 2021-09-01 │          300 │
│   2 │ 2021-09-01 │          600 │
└─────┴────────────┴──────────────┘

--更新明细数据,物化视图中的数据实时计算更新
insert into orders values(1,100,toDate(now()),1);
select uid,ctime,sumMerge(mm) from orders_agg_view group by uid,ctime;
┌─uid─┬──────ctime─┬─sumMerge(mm)─┐
│   1 │ 2021-09-01 │          400 │
│   2 │ 2021-09-01 │          600 │
└─────┴────────────┴──────────────┘
经验分享 程序员 微信小程序 职场和发展