ClickHouse - 将相似条目合并成一个新条目

Posted

技术标签:

【中文标题】ClickHouse - 将相似条目合并成一个新条目【英文标题】:ClickHouse - Merge similar entries into a new one 【发布时间】:2019-07-09 07:18:12 【问题描述】:

这是我在 ClickHouse 中当前的(简化的)模型:

凭据表

用户:字符串 域:字符串 密码:字符串 泄漏:UInt64

leak 字段是对泄漏 id 的引用。

泄漏表

id: UInt64 名称:字符串 描述:字符串 日期:字符串

我正在为Credential 使用 MergeTree 引擎,为Leak 使用日志。 有时,会插入两个相同的凭据,例如:|用户 |域名 |密码 | 0 ||用户 |域名 |密码 | 1 |

我想把它变成:|用户 |域名 |密码 | [0, 1] |

我已阅读有关 ReplacingMergeTree 的信息,但除了 version 参数之外,我没有找到其他方法来指定一些重写/删除规则。

我的问题是我有数十亿个条目,在插入之前处理数据听起来很疯狂。即使 ClickHouse 的响应时间非常短,检查我尝试插入的每个新凭据是否已经在其中似乎很荒谬,如果是,请更新其数据,对吗?

我正在尝试尽可能地减少磁盘存储,但看起来很难在保持这些令人难以置信的响应时间之间取得平衡。我在听你的想法。

【问题讨论】:

【参考方案1】:

有很多方法可以解决这个问题。

    您可以创建一个Materialized Table 以及您的实际表格。 您可以使用ReplacingMergeTree。 您可以改变(ALTER UPDATE)现有数据。 按原样使用您的表,但使用 groupArray 查询它以获得您想要的结果。

我在这里演示第四个解决方案。您只需像往常一样将数据插入MergeTree。但是当你查询它时,你使用groupArray 将所需的列滚动为基于其他列的数组。

假设你的桌子是这样的:

SELECT *
FROM mem

┌─a─────┬─b───────┬─c─────────┬─d─┐
│ user1 │ domain1 │ password1 │ 0 │
│ user1 │ domain1 │ password1 │ 1 │
│ user2 │ domain2 │ password2 │ 0 │
│ user2 │ domain2 │ password2 │ 2 │
└───────┴─────────┴───────────┴───┘

你使用groupArray来解决你的问题:

SELECT a, b, c, groupArray(d)
FROM mem
GROUP BY a, b, c

┌─a─────┬─b───────┬─c─────────┬─groupArray(d)─┐
│ user2 │ domain2 │ password2 │ [0,2]         │
│ user1 │ domain1 │ password1 │ [0,1]         │
└───────┴─────────┴───────────┴───────────────┘

【讨论】:

你能给我看一个表定义的例子和一个插入的例子,以确保我理解它吗?因为在我看来数据仍然存储两次而不是一次 @Chocorean,是的,数据仍然存储在多行中。如果只想要一行,可以使用ReplacingMergeTree 不能按问题解决。 CLickHouse 对此没有本机解决方案,我需要一种自定义的“替换规则”。但是nvm,我目前正在插入之前检查是否存在。 @Chocorean 实际上 Clickhouse 有一个本地解决方案,它被称为 AggregatingMergeTree。问题是,您的数据类型是数组,我无法将AggregatingMergeTree 中的列聚合为数组。正在努力。 是的,我的问题是我无法指定每次引擎聚合数据时应用的规则...很高兴看到这种功能!

以上是关于ClickHouse - 将相似条目合并成一个新条目的主要内容,如果未能解决你的问题,请参考以下文章

MySQL两个查询合并成一个结果

MySQL两个查询合并成一个结果

MySQL使用UNION ALL将两个查询合并成一个结果

Python将两个字典合并成一个字典

如何将多个TXT合并成一个TXT

如何把TXT内的每9行合并成一行