共计 3167 个字符,预计需要花费 8 分钟才能阅读完成。
简介:本文翻译自 Altinity 针对 ClickHouse 的系列技术文章。面向联机剖析解决(OLAP)的开源剖析引擎 ClickHouse,因其低劣的查问性能,PB 级的数据规模,简略的架构,被国内外公司宽泛采纳。本系列技术文章,将具体开展介绍 ClickHouse。
前言
本文翻译自 Altinity 针对 ClickHouse 的系列技术文章。面向联机剖析解决(OLAP)的开源剖析引擎 ClickHouse,因其低劣的查问性能,PB 级的数据规模,简略的架构,被国内外公司宽泛采纳。
阿里云 EMR-OLAP 团队,基于开源 ClickHouse 进行了系列优化,提供了开源 OLAP 剖析引擎 ClickHouse 的云上托管服务。EMR ClickHouse 齐全兼容开源版本的产品个性,同时提供集群疾速部署、集群治理、扩容、缩容和监控告警等云上产品性能,并且在开源的根底上优化了 ClickHouse 的读写性能,晋升了 ClickHouse 与 EMR 其余组件疾速集成的能力。拜访 https://help.aliyun.com/docum… 理解详情。
译者:何源(荆杭),阿里云计算平台事业部高级产品专家
ClickHouse 中的嵌套数据结构
在这篇博客文章中,咱们将理解 ClickHouse for MySQL 中的嵌套数据结构,以及如何将其与 PMM 联合应用来查看查问。
嵌套构造在关系数据库管理系统中并不常见。通常状况下,它只是立体表。有时,将非结构化信息存储在结构化数据库中会很不便。
咱们正在致力将 ClickHouse 调整为用于 Percona 监控和治理 (PMM) 的长期存储,尤其是存储无关查问的详细信息。咱们试图解决的问题之一是,对导致特定查问失败的不同谬误进行计数。
例如,对于日期为 2017-08-17 的查问:
"SELECT foo FROM bar WHERE id=?"
被执行了 1000 次。其中 25 次失败的错误代码为“1212”,8 次失败的错误代码为“1250”。当然,在关系数据中进行存储的传统办法是创立一个表 “Date, QueryID, ErrorCode, ErrorCnt”,而后对这个表执行 JOIN。遗憾的是,列式数据库在多个 Join 的状况下体现不佳,通常倡议应用非规范化表。
咱们能够为每个可能的 ErrorCode 创立一个列,但这并不是最优解。可能有成千上万的列,而且大多数时候它们都是空的。
在这种状况下,ClickHouse 提出了嵌套数据结构。对于咱们的状况,这些能够定义为:
CREATE TABLE queries
(
Period Date,
QueryID UInt32,
Fingerprint String,
Errors Nested
(
ErrorCode String,
ErrorCnt UInt32
)
)Engine=MergeTree(Period,QueryID,8192);
这个解决方案有显著的问题:咱们如何在这个表中插入数据?咱们如何提取它?
咱们先从 INSERT 开始。插入可能如下所示:
INSERT INTO queries VALUES ('2017-08-17',5,'SELECT foo FROM bar WHERE id=?',['1220','1230','1212'],[5,6,2])
这意味着 2017-08-17 期间插入的查问呈现了 5 次谬误 1220,6 次谬误 1230,2 次谬误 1212。
那么在不同的日期,它可能会产生不同的谬误:
INSERT INTO queries VALUES ('2017-08-18',5,'SELECT foo FROM bar WHERE id=?',['1220','1240','1258'],[3,2,1])
让咱们看一下 SELECT 数据的办法。十分根底的 SELECT:
SELECT *
FROM queries
|_____Period_|_QueryID_|_Fingerprint_|_Errors.ErrorCode_______|_Errors.ErrorCnt_|
| 2017-08-17 | 5 | SELECT foo | ['1220','1230','1212'] | [5,6,2] |
| 2017-08-18 | 5 | SELECT foo | ['1220','1240','1260'] | [3,16,12] |
|____________|_________|_____________|________________________|_________________|
如果咱们想应用更相熟的表格输入,则能够应用 ARRAY JOIN 扩大:
SELECT *
FROM queries
ARRAY JOIN Errors
┌─────Period─┬─QueryID─┬─Fingerprint─┬─Errors.ErrorCode─┬─Errors.ErrorCnt─┐
│ 2017-08-17 │ 5 │ SELECT foo │ 1220 │ 5 │
│ 2017-08-17 │ 5 │ SELECT foo │ 1230 │ 6 │
│ 2017-08-17 │ 5 │ SELECT foo │ 1212 │ 2 │
│ 2017-08-18 │ 5 │ SELECT foo │ 1220 │ 3 │
│ 2017-08-18 │ 5 │ SELECT foo │ 1240 │ 16 │
│ 2017-08-18 │ 5 │ SELECT foo │ 1260 │ 12 │
└────────────┴─────────┴─────────────┴──────────────────┴─────────────────┘
然而,通常咱们心愿看到多个期间的聚合,这能够通过传统的聚合函数来实现:
SELECT
QueryID,
Errors.ErrorCode,
SUM(Errors.ErrorCnt)
FROM queries
ARRAY JOIN Errors
GROUP BY
QueryID,
Errors.ErrorCode
┌─QueryID─┬─Errors.ErrorCode─┬─SUM(Errors.ErrorCnt)─┐
│ 5 │ 1212 │ 2 │
│ 5 │ 1230 │ 6 │
│ 5 │ 1260 │ 12 │
│ 5 │ 1240 │ 16 │
│ 5 │ 1220 │ 8 │
└─────────┴──────────────────┴──────────────────────┘
如果咱们别具匠心,每个 QueryID 只返回一行,咱们也能够这么做:
SELECT
QueryID,
groupArray((ecode, cnt))
FROM
(
SELECT
QueryID,
ecode,
sum(ecnt) AS cnt
FROM queries
ARRAY JOIN
Errors.ErrorCode AS ecode,
Errors.ErrorCnt AS ecnt
GROUP BY
QueryID,
ecode
)
GROUP BY QueryID
┌─QueryID─┬─groupArray(tuple(ecode, cnt))──────────────────────────────┐
│ 5 │ [('1230',6),('1212',2),('1260',12),('1220',8),('1240',16)] │
└─────────┴────────────────────────────────────────────────────────────┘
论断
ClickHouse 提供了灵便的形式来存储数据,只管它是一个列式数据库,但能够实现较低的结构化水平,并提供各种函数来提取和聚合数据。
后续
您曾经理解了在 ClickHouse 中解决实时更新相干内容,本系列还包含其余内容:
- 在 ClickHouse 中解决实时更新
- 应用新的 TTL move,将数据存储在适合的中央
- 在 ClickHouse 物化视图中应用 Join
- ClickHouse 聚合函数和聚合状态
- ClickHouse 中的嵌套数据结构(本文)
原文链接
本文为阿里云原创内容,未经容许不得转载。