关于数据结构:ClickHouse-技术系列-ClickHouse-中的嵌套数据结构

43次阅读

共计 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 中的嵌套数据结构(本文)

原文链接
本文为阿里云原创内容,未经容许不得转载。

正文完
 0