Clickhouse表引擎之CollapsingMergeTree引擎的原理与使用

前言

继续上次关于clickhouse的一些踩坑点,今天讲讲另外一个表引擎——CollapsingMergeTree。这个对于引擎对于数据量较大的场景是个不错的选择。注意,选择clickhouse的一般原因都是为了高效率查询,提高用户体验感,说白了就是以空间换时间,clickhouse的一个关键设计就是数据的合并。

CollapsingMergeTree官方文档说明

该引擎继承于 MergeTree,并在数据块合并算法中添加了折叠行的逻辑。

CollapsingMergeTree 会异步的删除(折叠)这些除了特定列 Sign 有 1 和 -1 的值以外,其余所有字段的值都相等的成对的行。没有成对的行会被保留。

注意:折叠其实就是跟合并概念类似的意思,这个时间是不一定的,有可能马上合并,有可能过一阵子合并,根本原因是因为合并数据涉及频繁的磁盘IO和空间占用。我猜测它合并一般选择数据库使用频率较低的时候合并。

这个说明什么意思呢?

如果仔细阅读,应该可以理解。就是说,创建表的时候,需要指定一个字段,比如官方的字段用sign表示,用来存一个标志位,标志位只能为-1和1。这样后面如果存在两条记录,除了标志位不一样以外,其他字段完全相同,那么在后续后台数据合并的时候,这两条数据会被相互抵消,彻底地被物理删除。

实操讲解

创建一张表
CREATE TABLE IF NOT EXISTS test (`advertiser_account_group_id` Int64 COMMENT '项目ID',`landing_page_id` Int64 COMMENT '落地页ID',`statistic_date` DateTime COMMENT '统计日期',`landing_page_channel_id` Int64 COMMENT '渠道ID',`page_view_num` Int64 DEFAULT 0 COMMENT '浏览数',`form_submit_num` Int64 DEFAULT 0 COMMENT '表单提交数',`sign` INT8 COMMENT '标志位' ) ENGINE = CollapsingMergeTree ( sign ) 
PARTITION BY toYYYYMM ( statistic_date ) 
PRIMARY KEY ( advertiser_account_group_id, landing_page_id, landing_page_channel_id, statistic_date ) 
ORDER BY( advertiser_account_group_id, landing_page_id, landing_page_channel_id, statistic_date ) 
COMMENT '测试表';
插入一条sign = 1的数据
INSERT INTO test3 ( advertiser_account_group_id, landing_page_id, landing_page_channel_id, statistic_date, page_view_num, form_submit_num, sign )VALUES(1,2,3,'2024-01-14 11:00:00',10,20,1)

这时候表里只有这一条标志位为1的数据,并且它不存在一条标志位为-1的数据,他就会一直存在于数据库中。假设这个数据我洗错了,需要对他进行修正,因为我这次的业务,涉及到清理的历史数据量级是数十亿的广告pv数据,所以不能直接对表记录进行更新,这个是clickhouse数据库的一个瓶颈。那怎么办呢,我这里是按照天维度进行数据清洗,所以在重新插入修正后的数据之前,先要查询出来我这个时间段内的历史数据,把查询出来的数据,将sign置为-1,再重新插一份到数据库,利用CollapsingMergeTree表隐情的折叠机制自动进行删除。这个过程,查询历史数据的步骤非常关键,按照官方文档里面,涉及数值的字段,需要用sum函数进行查询,SQL如下:

SELECTadvertiser_account_group_id,landing_page_id,landing_page_channel_id,statistic_date,sum( page_view_num * sign ) AS page_view_num,sum( form_submit_num * sign ) AS form_submit_num 
FROMtest3 where statistic_date BETWEEN '2024-01-14 00:00:00' and '2024-01-14 23:59:59'
GROUP BYadvertiser_account_group_id,landing_page_id,landing_page_channel_id,statistic_date 
HAVINGsum( sign ) > 0

这里一定要这样写,不能直接用如下的SQL写,否则你查询数来的数据大概率是错的:

    SELECTadvertiser_account_group_id,landing_page_id,landing_page_channel_id,statistic_date,sum(page_view_num),sum(form_submit_num)
FROMtest3where statistic_date BETWEEN '2024-01-14 00:00:00' and '2024-01-14 23:59:59' and sign > 0
GROUP BYadvertiser_account_group_id,landing_page_id,landing_page_channel_id,statistic_date

假设我在原有只有一条数据的基础上,再插一条标志位为-1的数据,其他字段一模一样

INSERT INTO test3 ( advertiser_account_group_id, landing_page_id, landing_page_channel_id, statistic_date, page_view_num, form_submit_num, sign )VALUES(1,2,3,'2024-01-14 11:00:00',10,20,-1)

如果直接使用第二个SQL查询,那么查询出来的结果就是第一条数据,如果数据还没有进行合并,我们查出来之后,再次将这一条数据sign = 1的数据设置成sign = -1,再插入数据库,这时候,数据效果就是这样

会存在两条sign=-1的数据,如果后面反复执行这个清洗任务,你插入的数据除了标志位不一样,其他都是一样的情况下,你会发现,你的数据怎么莫名其妙消失了,因为可能会出现你的sign = 1的数据跟数据库里面sign = -1的数据折叠抵消了。因为它合并的时间是不一定的,有可能马上合并,有可能几天之后才合并,所以如果你查询的姿势不对,你的数据就会一直错下去。

所以,正确的查询姿势,必须按照文档说明的取查询,案例可以直接查看官网的Demo或者我的这个也可以。

写在最后

好了,今天的内容就分享到这里,这篇文章有需要的可以好好收藏理解一下,在使用clickhouse的场景中,是个非常不错的选择。它的设计很巧妙,clickhouse还是很强大的,就是需要理解它的文档说明,姿势对了,他就很香,欢迎持续关注"安前码后",点击下方名片页,更多工作中实用干货会持续输出中。

觉得有帮助的话,帮忙意见三连,感激涕零。
加油,铁子们!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/410419.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跨站点请求伪造攻击 - Cross Site Request Forgery (CSRF)

什么是CSRF 最好理解CSRF攻击的方式是看一个具体的例子。 假设你的银行网站提供一个表单,允许当前登录用户将钱转账到另一个银行账户。例如,转账表单可能如下所示: <form method="post"action="/transfer"> <

Invalid bound statement (not found)(xml文件创建问题)

目录 解决方法&#xff1a; 这边大致讲一下我的经历&#xff0c;不想看的直接点目录去解决方法 今天照着老师视频学习&#xff0c;中间老师在使用动态SQL时&#xff0c;直接复制了一份&#xff0c;我想这么简单的一个&#xff0c;我直接从网上找内容创建一个好了&#xff0c;…

前端学习路径

菜鸟感觉很多人不太知道菜鸟写的博客是一个可以跟着学习、一起深入理解的过程&#xff0c;其中包括了菜鸟从刚开始学习到后面重新学习&#xff0c;再到后面进入学框架等一系列学习过程、知识和感悟&#xff0c;所以菜鸟把自己的博客整理成一个目录提取出来&#xff0c;好让读者…

彻底解决charles抓包https乱码的问题

最近做js逆向&#xff0c;听说charles比浏览器抓包更好用&#xff0c;结果发现全是乱码&#xff0c;根本没法用。 然后查询网上水文&#xff1a;全部都是装证书&#xff0c;根本没用&#xff01; 最后终于找到解决办法&#xff0c;在这里记录一下&#xff1a; 乱码的根本原因…

【Maven】002-Maven 安装和配置

【Maven】002-Maven 安装和配置 文章目录 【Maven】002-Maven 安装和配置一、官网1、官网2、历史版本列表3、Maven 仓库地址 二、下载 Maven 3.8.8 版本1、进入 Maven 3.8.8 版本发行说明页2、进入下载页3、下载4、下载得到 apache-maven-3.8.8-bin.zip 三、Maven 安装1、将安装…

C# 图解教程 第5版 —— 第22章 命名空间和程序集

文章目录 22.1 引用其他程序集22.2 命名空间22.2.1 命名空间名称22.2.2 命名空间的补充22.2.3 命名空间跨文件伸展22.2.4 嵌套命名空间 22.3 using 指令22.3.1 using 命名空间指令22.3.2 using 别名指令22.3.3 using static 指令 22.4 程序集的结构22.5 程序集标识符22.6 强命名…

力扣刷MySQL-第二弹(详细解析)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;力扣刷题讲解-MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出…

java SECS管理系统 将逐步推出 SECS 客户端(Passive) 管理系统 SECS快速开发平台 springboot secs开发平台

SECS管理系统 这是一套SECS客户端(Passive)&#xff0c;可以直接连接PLC设备,支持Modbus、三菱MC、欧姆龙Fine、OPC-UA、西门子S7设备等通信。 企业已经有了EAP软件&#xff0c;但是设备没有SECS通信功能&#xff0c;这时候可以使用这套框架&#xff0c;直接连接设备&#xff…

基本BGP配置试验 :配置 IBGP 和 EBGP

一、预习&#xff1a; BGP&#xff1a;Border Gateway Protocol 没有精妙的算法&#xff0c;但能承载大量的路由&#xff0c;它不生产路由&#xff0c;它是路由的搬运工 使用TCP做为传输层协议&#xff0c;端口号179&#xff0c;使用触发式路由更新 1. BGP路由…

MATLAB Deep learning

文章目录 Chapter 1: Machine Learning存在的问题过拟合Overfitting解决过拟合 regularization and validationregularization 正则化validation 验证 机器学习的类型有监督学习分类Classification回归Regression 无监督学习聚类 强化学习 Chapter 2: Neural Network神经网络的…

【iOS】数据存储方式总结(持久化)沙盒结构

在iOS开发中&#xff0c;我们经常性地需要存储一些状态和数据&#xff0c;比如用户对于App的相关设置、需要在本地缓存的数据等等&#xff0c;本篇文章将介绍六个主要的数据存储方式 iOS中数据存储方式&#xff08;数据持久化&#xff09; 根据要存储的数据大小、存储数据以及…

cookie和session的工作过程和作用:弥补http无状态的不足

cookie是客户端浏览器保存服务端数据的一种机制。当通过浏览器去访问服务端时&#xff0c;服务端可以把状态数据以key-value的形式写入到cookie中&#xff0c;存储到浏览器。浏览器下次去服务服务端时&#xff0c;就可以把这些状态数据携带给服务器端&#xff0c;服务器端可以根…