VersionedCollapsingMergeTree引擎继承自MergeTree并将折叠行的逻辑添加到合并数据部分的算法中。VersionedCollapsingMergeTree用于相同的目的折叠树但使用不同的折叠算法,允许以多个线程的任何顺序插入数据。特别是,Version列有助于正确折叠行,即使它们以错误的顺序插入。相比之下,CollapsingMergeTree只允许严格连续插入。

VersionedCollapsingMergeTree引擎的作用如下:

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

建表语法

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, version)两个特殊的参数。

sign — 指定行类型的列名:1是一个“state”行,-1是一个“cancel”行列数据类型应为Int8.

version — 指定对象状态版本的列名。列数据类型应为UInt*.

使用场景

考虑一种情况,您需要为某个对象保存不断变化的数据。对于一个对象有一行,并在发生更改时更新该行是合理的。但是,对于数据库管理系统来说,更新操作非常昂贵且速度很慢,因为它需要重写存储中的数据。如果需要快速写入数据,则不能接受更新,但可以按如下顺序将更改写入对象。使用 Sign 列写入行时。如果Sign=1这意味着该行是一个对象的状态(让我们把它称为“state”行)。如果Sign=-1它指示具有相同属性的对象的状态的取消(让我们称之为“cancel”行)。 还可以使用 Version 列,它应该用单独的数字标识对象的每个状态。

例如,我们要计算用户在某个网站上访问了多少页面以及他们在那里的时间。在某个时间点,我们用用户活动的状态写下面的行:

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 5 │ 146 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘

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

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 5 │ 146 │ -1 │
│ 4324182021466249494 │ 6 │ 185 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘

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

第二行包含当前状态。

因为我们只需要用户活动的最后一个状态,所以需要删除,折叠对象的无效(旧)状态。VersionedCollapsingMergeTree会在在合并数据部分时执行此操作。

最终折叠之后的结果如下。

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
│ 4324182021466249494 │ 5 │ 146 │ 1 │ 1 |
│ 4324182021466249494 │ 5 │ 146 │ -1 │ 1 |
└─────────────────────┴───────────┴──────────┴──────┴─────────┘

对于使用VersionedCollapsingMergeTree有下面三个需要注意的点。

  1. 写入数据的程序应该记住对象的状态以取消它。该“cancel”字符串应该是“state”与相反的字符串Sign。这增加了存储的初始大小,但允许快速写入数据。
  2. 列中长时间增长的数组由于写入负载而降低了引擎的效率。数据越简单,效率就越高。
  3. SELECT结果很大程度上取决于对象变化历史的一致性。准备插入数据时要准确。不一致的数据将导致不可预测的结果,例如会话深度等非负指标的负值。

合并算法

合并算法主要是下面两个。

  • 当ClickHouse合并数据部分时,它会删除具有相同主键和版本但Sign值不同的一对行.行的顺序并不重要。
  • 当ClickHouse插入数据时,它会按主键对行进行排序。如果Version列不在主键中,ClickHouse将其隐式添加到主键作为最后一个字段并使用它进行排序。

ClickHouse不保证具有相同主键的所有行都将位于相同的结果数据部分中,甚至位于相同的物理服务器上。对于写入数据和随后合并数据部分都是如此。此外,ClickHouse流程SELECT具有多个线程的查询,并且无法预测结果中的行顺序。这意味着,如果有必要从VersionedCollapsingMergeTree表中得到完全“collapsed”的数据,聚合是必需的。

也就是说ClickHouse并不保证查询出来的数据一定是经过合并折叠的。如果要保证一定经过折叠合并,需要查询的时候使用GROUP BY和聚合函数。

要计算数量,使用sum(Sign)而不是count()。要计算的东西的总和,使用sum(Sign * x)而不是sum(x),并添加HAVING sum(Sign) > 0。可以在一定程度上避免数据未折叠导致的数据问题。

如果您需要手动折叠合并,但是,如果没有聚合(例如,要检查是否存在其最新值与某些条件匹配的行),则可以使用FINAL修饰FROM条件这种方法效率低下,不应与大型表一起使用。

使用例子、

示例数据:

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
│ 4324182021466249494 │ 5 │ 146 │ 1 │ 1 |
│ 4324182021466249494 │ 5 │ 146 │ -1 │ 1 |
│ 4324182021466249494 │ 6 │ 185 │ 1 │ 2 |
└─────────────────────┴───────────┴──────────┴──────┴─────────┘

创建表:

CREATE TABLE UAct
(
UserID UInt64,
PageViews UInt8,
Duration UInt8,
Sign Int8,
Version UInt8
)
ENGINE = VersionedCollapsingMergeTree(Sign, Version)
ORDER BY UserID

插入数据:


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将创建一个数据部分,并且永远不会执行任何合并。

获取数据:

SELECT * FROM UAct

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
│ 4324182021466249494 │ 5 │ 146 │ 1 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┴─────────┘
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
│ 4324182021466249494 │ 5 │ 146 │ -1 │ 1 │
│ 4324182021466249494 │ 6 │ 185 │ 1 │ 2 │
└─────────────────────┴───────────┴──────────┴──────┴─────────┘

我们在这里看到了什么,折叠的合并部分在哪里?我们使用两个创建了两个数据部分INSERT查询。该SELECT查询是在两个线程中执行的,结果是行的随机顺序。由于数据部分尚未合并,因此未发生折叠合并。 ClickHouse在我们无法预测的未知时间点合并数据部分。

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

SELECT
UserID,
sum(PageViews * Sign) AS PageViews,
sum(Duration * Sign) AS Duration,
Version
FROM UAct
GROUP BY UserID, Version
HAVING sum(Sign) > 0 ┌──────────────UserID─┬─PageViews─┬─Duration─┬─Version─┐
│ 4324182021466249494 │ 6 │ 185 │ 2 │
└─────────────────────┴───────────┴──────────┴─────────┘

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

SELECT * FROM UAct FINAL

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
│ 4324182021466249494 │ 6 │ 185 │ 1 │ 2 │
└─────────────────────┴───────────┴──────────┴──────┴─────────┘

资料分享

ClickHouse经典中文文档分享

参考文章

ClickHouse(14)ClickHouse合并树MergeTree家族表引擎之VersionedCollapsingMergeTree详细解析的更多相关文章

  1. ClickHouse(10)ClickHouse合并树MergeTree家族表引擎之ReplacingMergeTree详细解析

    目录 建表语法 数据处理策略 资料分享 参考文章 MergeTree拥有主键,但是它的主键却没有唯一键的约束.这意味着即便多行数据的主键相同,它们还是能够被正常写入.在某些使用场合,用户并不希望数据表 ...

  2. ClickHouse(11)ClickHouse合并树MergeTree家族表引擎之SummingMergeTree详细解析

    目录 建表语法 数据处理 汇总的通用规则 AggregateFunction 列中的汇总 嵌套结构数据的处理 资料分享 参考文章 SummingMergeTree引擎继承自MergeTree.区别在于 ...

  3. ClickHouse(13)ClickHouse合并树MergeTree家族表引擎之CollapsingMergeTree详细解析

    目录 建表 折叠 数据 算法 资料分享 参考文章 该引擎继承于MergeTree,并在数据块合并算法中添加了折叠行的逻辑.CollapsingMergeTree会异步的删除(折叠)这些除了特定列Sig ...

  4. ClickHouse(12)ClickHouse合并树MergeTree家族表引擎之AggregatingMergeTree详细解析

    目录 建表语法 查询和插入数据 数据处理逻辑 ClickHouse相关资料分享 AggregatingMergeTree引擎继承自 MergeTree,并改变了数据片段的合并逻辑.ClickHouse ...

  5. Clickhouse表引擎之MergeTree

    1.概述 在Clickhouse中有多种表引擎,不同的表引擎拥有不同的功能,它直接决定了数据如何读写.是否能够并发读写.是否支持索引.数据是否可备份等等.本篇博客笔者将为大家介绍Clickhouse中 ...

  6. UniqueMergeTree:支持实时更新删除的 ClickHouse 表引擎

    UniqueMergeTree 开发的业务背景 首先,我们看一下哪些场景需要用到实时更新. 我们总结了三类场景: 第一类是业务需要对它的交易类数据进行实时分析,需要把数据流同步到 ClickHouse ...

  7. Clickhouse表引擎探究-ReplacingMergeTree

    作者:耿宏宇 1 表引擎简述 1.1 官方描述 MergeTree 系列的引擎被设计用于插入极大量的数据到一张表当中.数据可以以数据片段的形式一个接着一个的快速写入,数据片段在后台按照一定的规则进行合 ...

  8. ClickHouse入门:表引擎-HDFS

    前言插件及服务器版本服务器:ubuntu 16.04Hadoop:2.6ClickHouse:20.9.3.45 文章目录 简介 引擎配置 HDFS表引擎的两种使用形式 引用 简介 ClickHous ...

  9. ClickHouse(02)ClickHouse架构设计介绍概述与ClickHouse数据分片设计

    ClickHouse核心架构设计是怎么样的?ClickHouse核心架构模块分为两个部分:ClickHouse执行过程架构和ClickHouse数据存储架构,下面分别详细介绍. ClickHouse执 ...

  10. 【大数据面试】ClickHouse:介绍、特点、数据类型、引擎、操作、副本、分片

    1.介绍 开源的列式存储数据库(DBMS),由C++编写,用于在线分析处理查询(OLAP) 可以通过SQL查询实时生成分析数据报告 解释: DBMS:数据库管理系统 常见的列式存储数据库:Hbase. ...

随机推荐

  1. 火山引擎 DataLeap:如何构建一套完整、易用的数据标准体系

    数据标准是数据治理体系中的核心要素之一.   一方面,统一的数据标准可以在复杂的业务场景下,帮助团队对齐数据口径,提升数据在分析.诊断等场景的质量与效率:另一方面,数仓团队与分析师团队也需要沉淀一套敏 ...

  2. 火山引擎 DataLeap 一招教你避坑“数据开发”中的资源隔离问题

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 在离线数仓开发过程中,研发人员需要根据业务变化,在开发/生产环境中不断切换.解析.调试.以往,企业一般通过人工方式 ...

  3. 告别数据开发中的人工审核!火山引擎 DataLeap 落地“自动校验开发规范”能力

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 近期,火山引擎 DataLeap 智能市场上线"数仓建表规范"功能,该功能通过规范数仓场景下的 ...

  4. Jenkins Pipeline 流水线 - 拉代码(SVN) + Maven 编译打包

    Jenkins Pipeline 流水线 步骤 拉取SVN代码 -> Maven 构建 -> Docker 编译 -> 发布至阿里云仓库 -> K8S 更新 Jenkins插件 ...

  5. BBS项目(三):侧边栏筛选功能 文章详情页搭建 点赞点踩功能 文章根评论功能

    目录 复习与补充 侧边栏筛选功能 文章详情页搭建 点赞点踩样式搭建 点赞点踩功能完善 文章评论前期准备 文章根评论业务逻辑 练习 复习与补充 admin后台管理复习: admin.py文件中注册模型表 ...

  6. ElasticSearch 创建、删除索引

    创建索引: PUT http://IP:Port/mytest-statistics { "aliases": {}, "mappings": { " ...

  7. C++ 20 标准协程入门教程

    基本概念 (是什么) 协程(coroutine): 是一种特殊的函数,其可以被暂停(suspend), 恢复执行(resume).一个协程可 以被多次调用. 协程(coroutine): 分为stac ...

  8. Mac | 解决 MacOS 配置 Maven 出现的 Java_Home Error

    1. 错误信息 2. 解决方案 2.1 对于Windows系统下解决方案 https://blog.csdn.net/frankarmstrong/article/details/69945774,在 ...

  9. 【每日一题】7.月月查华华的手机 (枚举 or 序列自动机)

    题目链接:Here 题意总结:\(N\) 次查询串 \(B\) 是否是 \(A\) 的子序列. 思路一 个人做法,枚举原字符串的每一位,如果匹配当前字符串的字符则 m++ 直到字符串枚举完毕或者 m ...

  10. 【SpringBoot】 启动后会调用执行的方法的 (五种方式)

    在 SpringBoot 工程 启动后, 会调用执行方法的五种方式: 亲自测试, 按照执行顺序如下: 第一种: @Component public class SpringContext1 { @Po ...