前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >客快物流大数据项目(九十六):ClickHouse的VersionedCollapsingMergeTree深入了解

客快物流大数据项目(九十六):ClickHouse的VersionedCollapsingMergeTree深入了解

原创
作者头像
Lansonli
发布2022-12-28 17:13:27
6990
发布2022-12-28 17:13:27
举报
文章被收录于专栏:Lansonli技术博客

ClickHouse的VersionedCollapsingMergeTree深入了解

该引擎继承自 MergeTree 并将折叠行的逻辑添加到合并数据部分的算法中,这个引擎:

  • 允许快速写入不断变化的对象状态
  • 删除后台中的旧对象状态,这显著降低了存储体积

VersionedCollapsingMergeTree 用于相同的目的折叠树 ,但使用不同的折叠算法,允许以多个线程的任何顺序插入数据。 特别是, Version 列有助于正确折叠行,即使它们以错误的顺序插入。

相比之下, CollapsingMergeTree 只允许严格连续插入。

一、创建VersionedCollapsingMergeTree引擎表的语法

语法结构

代码语言:javascript
复制
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
) ENGINE = VersionedCollapsingMergeTree(sign, version)
    [PARTITION BY expr]
    [ORDER BY expr]
    [SAMPLE BY expr]
    [SETTINGS name=value, ...]

VersionedCollapsingMergeTree(sign)参数说明

Sign是列名称,必须是Int8类型,用来标志Sign列。Sign列值为1是状态行,为-1是取消行。

二、折叠数据

考虑一种情况,您需要为某个对象保存不断变化的数据。对于一个对象有一行,并在发生更改时更新该行是合理的。但是,对于数据库管理系统来说,更新操作非常昂贵且速度很慢,因为它需要重写存储中的数据。 如果需要快速写入数据,则不能接受更新,但可以按如下顺序将更改写入对象。

使用 Sign 列写入行时。 如果 Sign = 1 这意味着该行是一个对象的状态(让我们把它称为 “state” 行)。 如果 Sign = -1 它指示具有相同属性的对象的状态的取消(让我们称之为 “cancel” 行)。 还可以使用 Version 列,它应该用单独的数字标识对象的每个状态。

例如,我们要计算用户在某个网站上访问了多少页面以及他们在那里的时间。

在某个时间点,我们用用户活动的状态写下面的行:

在稍后的某个时候,我们注册用户活动的变化,并用以下两行写入它。

第一行取消对象(用户)的先前状态。 它应该复制已取消状态的所有字段,除了 Sign.

第二行包含当前状态。因为我们只需要用户活动的最后一个状态行

可以删除,折叠对象的无效(旧)状态。 VersionedCollapsingMergeTree 在合并数据部分时执行此操作。

三、使用示例

创建表:

代码语言:javascript
复制
CREATE TABLE UAct
(
    UserID UInt64,
    PageViews UInt8,
    Duration UInt8,
    Sign Int8,
    Version UInt8
)
ENGINE = VersionedCollapsingMergeTree(Sign, Version)
ORDER BY UserID

插入数据:

代码语言:javascript
复制
INSERT INTO UAct VALUES (4324182021466249494, 5, 146, 1, 1);
INSERT INTO UAct VALUES (4324182021466249494, 5, 146, -1, 1),(4324182021466249494, 6, 185, 1, 2);

我们用两个 INSERT 查询以创建两个不同的数据部分。 如果我们使用单个查询插入数据,ClickHouse将创建一个数据部分,并且永远不会执行任何合并。

获取数据:

代码语言:javascript
复制
SELECT *  FROM UAct

我们在这里看到了什么,折叠的部分在哪里?

我们使用两个创建了两个数据部分 INSERT 查询。

该 SELECT 查询是在两个线程中执行的,结果是行的随机顺序。

由于数据部分尚未合并,因此未发生折叠。 ClickHouse在我们无法预测的未知时间点合并数据部分。

这就是为什么我们需要聚合:

代码语言:javascript
复制
SELECT
    UserID,
    sum(PageViews * Sign) AS PageViews,
    sum(Duration * Sign) AS Duration,
    Version
FROM UAct
GROUP BY UserID, Version
HAVING sum(Sign) > 0;

如果我们不需要聚合,并希望强制折叠,我们可以使用 FINAL 修饰符 FROM

代码语言:javascript
复制
SELECT * FROM UAct FINAL

这是一个非常低效的方式来选择数据。 不要把它用于数据量大的表。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ​ClickHouse的VersionedCollapsingMergeTree深入了解
    • 一、创建VersionedCollapsingMergeTree引擎表的语法
      • 二、折叠数据
        • 三、使用示例
        相关产品与服务
        对象存储
        对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档