ClickHouse(十五):Clickhouse MergeTree系列表引擎 - AggregatingMergeTree

news/2025/2/22 4:24:15/

 进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容!

🏡个人主页:含各种IT体系技术,IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客

📌订阅:拥抱独家专题,你的订阅将点燃我的创作热情!

👍点赞:赞同优秀创作,你的点赞是对我创作最大的认可!

⭐️ 收藏:收藏原创博文,让我们一起打造IT界的荣耀与辉煌!

✏️评论:留下心声墨迹,你的评论将是我努力改进的方向!


目录

1. AggregatingMergeTree建表语句

2. 示例一

3. 示例二


该表引擎继承自MergeTree,可以使用 AggregatingMergeTree 表来做增量数据统计聚合。如果要按一组规则来合并减少行数,则使用 AggregatingMergeTree 是合适的。AggregatingMergeTree是通过预先定义的聚合函数计算数据并通过二进制的格式存入表内。

与SummingMergeTree的区别在于:SummingMergeTree对非主键列进行sum聚合,而AggregatingMergeTree则可以指定各种聚合函数。对某些字段需要进行聚合时,需要在创建表字段时指定成AggregateFunction类型。

1. 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, ...]

2. 示例一

#创建表 t_aggregating_mt ,使用AggregatingMergeTree引擎,指定salary字段是聚合字段node1 :) create table t_aggregating_mt(:-] id UInt8,:-] name String,:-] age UInt8,:-] loc String,:-] dept String,:-] workdays UInt8,:-] salary AggregateFunction(sum,Decimal32(2)):-] ) engine = AggregatingMergeTree():-] order by (id,age):-] primary key id:-] partition by loc;
  • 注意:

对于AggregateFunction类型的列字段,在进行数据的写入和查询时与其他的表引擎有很大区别,在写入数据时,需要调用 *-State 函数;而在查询数据时,则需要调用相应的 *-Merge 函数。

对于上面的建表语句而言,需要使用sumState函数进行数据插入。

#向表 t_aggregating_mt 中插入数据,插入方式与之前方式不同node1 :) insert into t_aggregating_mt select 1,'张三',18,'北京','java',18,sumState(toDecimal32(10000,2));node1 :) insert into t_aggregating_mt select 2,'李四',19,'上海','java',22,sumState(toDecimal32(8000,2));node1 :) insert into t_aggregating_mt select 3,'王五',20,'北京','java',26,sumState(toDecimal32(12000,2));

查询数据时,如果正常语句查询,aggregateFunction类型的列不会正常显示数据,针对以上的数据需要使用sumMerge来展示数据。

#错误方式查询表 t_aggregating_mt 中的数据node1 :) select * from t_aggregating_mt; ┌─id─┬─name─┬─age─┬─loc──┬─dept─┬─workdays─┬─salary─┐│  1  │ 张三  │  18  │ 北京  │ java │       18  │ @B      │└────┴──────┴─────┴──────┴──────┴──────────┴────────┘┌─id─┬─name─┬─age─┬─loc──┬─dept─┬─workdays─┬─salary─┐│  2 │ 李四  │  19  │ 上海  │ java  │       22  │ 5       │└────┴──────┴─────┴──────┴──────┴──────────┴────────┘┌─id─┬─name─┬─age─┬─loc──┬─dept─┬─workdays─┬─salary─┐│  3  │ 王五  │  20 │ 北京  │  java │       26  │ O       │└────┴──────┴─────┴──────┴──────┴──────────┴────────┘#正确方式查询表 t_aggregating_mt中的数据,注意需要跟上groupBynode1 :) select * ,sumMerge(salary) from t_aggregating_mt group by id,name ,age, loc,dept,workdays,salary ;┌─id─┬─name─┬─age─┬─loc──┬─dept─┬─workdays─┬─salary─┬─sumMerge(salary)─┐│  1 │ 张三   │  18 │ 北京  │ java  │       18  │ @B      │         10000.00   ││  3 │ 王五   │  20 │ 北京  │ java  │       26  │ O       │         12000.00   ││  2 │ 李四   │  19 │ 上海  │ java  │       22  │ 5       │          8000.00   │└────┴──────┴─────┴──────┴──────┴──────────┴────────┴──────────────────┘

向表中插入排序字段相同的数据进行分区聚合时,数据按照建表指定的聚合字段进行合并,其他的非聚合字段会保留最初的那条数据,新插入的数据对应的字段值会被舍弃。

# 向表中插入新的一条数据node1 :) insert into t_aggregating_mt select 1,'张三三',18,'北京','前端',22,sumState(toDecimal32(5000,2));#查询表中的数据,这里为了方便看到分区不合并,直接查询┌─id─┬─name─┬─age─┬─loc──┬─dept─┬─workdays─┬─salary─┐│  3  │ 王五  │  20 │ 北京   │ java │       26  │ O       │└────┴──────┴─────┴──────┴──────┴──────────┴────────┘┌─id─┬─name───┬─age─┬─loc──┬─dept─┬─workdays─┬─salary─┐│  1  │ 张三三  │  18  │ 北京  │ 前端   │       22  │  ¡      │└────┴────────┴─────┴──────┴──────┴──────────┴────────┘┌─id─┬─name─┬─age─┬─loc──┬─dept─┬─workdays─┬─salary─┐│  2  │ 李四  │  19 │ 上海  │ java  │       22  │ 5       │└────┴──────┴─────┴──────┴──────┴──────────┴────────┘┌─id─┬─name─┬─age─┬─loc──┬─dept─┬─workdays─┬─salary─┐│  1 │ 张三  │  18  │ 北京  │ java  │       18  │ @B      │└────┴──────┴─────┴──────┴──────┴──────────┴────────┘#使用optimize 命令合并相同分区数据node1 :) optimize table t_aggregating_mt;#再次查询表 t_aggregating_mt 表数据,salary 字段已经按照相同分区数据聚合node1 :) select *,sumMerge(salary)  from t_aggregating_mt group by id,name ,age,loc,dept,workdays,salary;┌─id─┬─name─┬─age─┬─loc──┬─dept─┬─workdays─┬─salary─┬─sumMerge(salary)─┐│  1  │ 张三  │  18 │ 北京  │ java  │       18  │ `ᔠ      │         15000.00  ││  3  │ 王五  │  20 │ 北京  │ java  │       26  │ O        │         12000.00  ││  2  │  李四 │  19 │ 上海  │ java  │       22  │ 5        │          8000.00  │└────┴──────┴─────┴──────┴──────┴──────────┴────────┴──────────────────┘

以上方式使用AggregatingMergeTree表引擎比较不方便,更多情况下,我们将AggregatingMergeTree作为物化视图的表引擎与MergeeTree搭配使用。

3. 示例二

#创建表 t_merge_base 表,使用MergeTree引擎node1 :) create table t_merge_base(:-] id UInt8,:-] name String,:-] age UInt8,:-] loc String,:-] dept String,:-] workdays UInt8,:-] salary Decimal32(2):-] )engine = MergeTree():-] order by (id,age):-] primary key id:-] partition by loc;#创建物化视图 view_aggregating_mt ,使用AggregatingMergeTree引擎node1 :) create materialized view  view_aggregating_mt:-] engine = AggregatingMergeTree() :-] order by id :-] as select :-] id,:-] name,:-] sumState(salary) as ss:-] from t_merge_base:-] group by id ,name ;#向表 t_merge_base 中插入数据node1 :) insert into t_merge_base values (1,'张三',18,'北京','大数据',24,10000),:-] (2,'李四',19,'上海','java',22,8000),:-] (3,'王五',20,'北京','java',26,12000);#查看 view_aggregating_mt视图数据node1 :) select *,sumMerge(ss)  from view_aggregating_mt group by id,name,ss;┌─id─┬─name─┬─ss─┬─sumMerge(ss)─┐│  2  │ 李四  │ 5  │      8000.00   ││  3  │ 王五  │ O  │     12000.00   ││  1  │ 张三  │ @B │     10000.00  │└────┴──────┴────┴──────────────┘#继续向表 t_merge_base中插入排序键相同的数据node1 :) insert into t_merge_base values (1,'张三三',18,'北京','前端',22,5000);#手动执行optimize 命令,合并物化视图 view_aggregating_mt 相同分区数据node1 :) optimize table view_aggregating_mt;#查询视图 view_aggregating_mt数据node1 :) select *,sumMerge(ss)  from view_aggregating_mt group by id,name,ss;┌─id─┬─name─┬─ss─┬─sumMerge(ss)─┐│  2  │ 李四  │ 5  │      8000.00   ││  1  │ 张三  │ `ᔠ│     15000.00   ││  3  │ 王五  │ O  │     12000.00   │└────┴──────┴────┴──────────────┘注意:通过普通MergeTree表与AggregatingMergeTree物化视图结合使用,MergeTree中存放原子数据,物化视图中存入聚合结果数据,可以提升数据查询效率。

👨‍💻如需博文中的资料请私信博主。



http://www.ppmy.cn/news/1016556.html

相关文章

Linux下的CGI服务器

一、概述 使用进程池,半同步/半异步并发模式。 同步进程:工作子进程负责进行具体的连接以及具体的I/O,顺序执行 异步进程:主进程监听连接事件,将连接任务分发给子线程 二、设计逻辑 1.设计进程池的创建逻辑 2.父…

【学习日记】【FreeRTOS】链表结构体及函数详解

写在前面 本文主要是对于 FreeRTOS 中链表相关内容的详细解释,代码大部分参考了野火FreeRTOS教程配套源码,作了一小部分修改。 一、结构体定义 主要包含三种结构体: 普通节点结构体结尾节点(mini节点)结构体链表结…

优化案例3:高频多union表关联穿插拼接完成计数

优化案例3:高频多union表关联穿插拼接完成计数 1. 引入2. 解决过程2.1 瓶颈定位思想2.2 定位解决过程2.2.1 子部分代码12.2.2 子部分代码2 2.3 优化结果 3. 优化心得 DM技术交流QQ群:940124259 1. 引入 已经很久没有发布文章,快沉底&#x…

Java进阶(1)——JVM的内存分配 反射Class类的类对象 创建对象的几种方式 类加载(何时进入内存JVM) 注解 反射+注解的案例

目录 引出java内存分配java内存分布概略图堆方法区常量池 创建对象内存分配 反射class文件的底层类加载顺序1.检查2.开辟静态资源空间3.常量池4.其他...5.创建一个唯一的类的对象获取Class对象的几种方式 创建对象几种方式new 看到new : new Book()反射 Class.forName(“包名.类…

开窗积累之学习更新版

1. 开窗使用1之 count range between current row and current row 将相同排序字段的值进行函数计算 selectsku_id,substr(create_date,1,7) date_month,order_id,create_date,sku_num*price,sum(sku_num*price) over (partition by sku_id order by substr(create_date,1,7)…

git clone 报错Filename too long

1.使用git clone代码,爆出Filename too long错误 2.原因分析 因为我很少看git clone日志,所以从未想过是clone异常,而且也看到代码clone下来了,所以我就显然以为代码clone成功,但是使用idea打开代码后发现大量代码无法…

Zebec Protocol 将进军尼泊尔市场,通过 Zebec Card 推动地区金融平等

流支付正在成为一种全新的支付形态,Zebec Protocol 作为流支付的主要推崇者,正在积极的推动该支付方案向更广泛的应用场景拓展。目前,Zebec Protocol 成功的将流支付应用在薪酬支付领域,并通过收购 WageLink 将其纳入旗下&#xf…

echarts实现中国地图下钻进入下一级行政区(地图钻取)

获取geo数据&#xff1a; 可以使用node爬虫获取数据 最好多爬几遍&#xff0c;因为有时候会获取错误 echarts实现 html <div ref"echarts-dom" class"echarts-content"></div>js: export default {data() {return {mapChart: null,addressC…