前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >「Clickhouse Array 的力量」1-2

「Clickhouse Array 的力量」1-2

作者头像
玖柒的小窝
修改2021-11-01 10:54:12
2.1K0
修改2021-11-01 10:54:12
举报
文章被收录于专栏:各类技术文章~各类技术文章~

可变数据建模

像键值对列表(也就是 dict/map)这样的可变数据结构会反复出现在我们日常的分析场景中,特别是那些涉及时间序列数据的问题。

以监测运行公共云的虚拟机为例。特定的虚拟机有我们想要测量的不同属性(如SSD存储的特定值),以及因操作虚拟机的团队而不同的标签(如应用程序类型)。因此,每条监控记录包含两个键值列表,其键值可能在不同的虚拟机之间和随着时间的推移而改变。

我们可以用一对数组来表示每个键值列表。一个数组提供属性名称,另一个数组提供相同数组索引的值。下面是我们如何在表定义中模拟虚拟机监控数据。因为有两种类型的键值,所以有两组数组:一个用于度量数据,另一个用于标签数据。

代码语言:javascript
复制
CREATE TABLE vm_data (
  datetime DateTime,  
  date Date default toDate(datetime),
  vm_id UInt32,  
  vm_type LowCardinality(String),  
  metrics_name Array(String),
  metrics_value Array(Float64),
  tags_name Array(String),  
  tags_value Array(String)
)
ENGINE = MergeTree()
PARTITION BY date 
ORDER BY (vm_type, vm_id, datetime)
复制代码

你可以直接使用嵌套的JSON结构加载数组,如下面所示的格式化好的:

代码语言:javascript
复制
[ { 
  "datetime": "2020-09-03 00:00:10",
  "vm_id": 6220,
  "vm_type": "m5.large",
  "metrics_name": [ "usage_idle", "ebs1_cap_gib", "ebs1_used_gib" ],
  "metrics_value": [ 80.2, 10.0, 7.6 ],
  "tags_name": [ "name", "group" ],
  "tags_value": [ "sfg-prod-01", "rtb" ]
},{
{
  "datetime": "2020-09-03 00:00:12",
  "vm_id": 6221,
  "vm_type": "m5ad.xlarge",
  "metrics_name": [ "usage_idle", "ssd1_cap_gib", "ssd1_used_gib" ],
  "metrics_value": [ 59.19, 75.0, 21.9 ],
  "tags_name": [ "name", "group", "owner" ],
  "tags_value": [ "mt-prod-65", "marketing", "casey" ]
} ]
复制代码

我们使用以下命令来加载我们的样本数据到ClickHouse。 jq 将记录从JSON数组中剥离出来,并将每个记录放在一个单行上,以符合 ClickHouse JSONEachRow 的输入格式:

代码语言:javascript
复制
cat vm_data.json |jq -c .[] | clickhouse-client --database arrays \
--query="INSERT INTO vm_data FORMAT JSONEachRow"
复制代码

一旦数据被加载,我们就可以使用SQL对其进行操作。我们将从选择单个记录开始:

代码语言:javascript
复制
SELECT *
FROM vm_data
LIMIT 1\G

/* sql answer*/
Row 1:
──────
datetime:      2020-09-03 00:00:10
date:          2020-09-03
vm_id:         6220
vm_type:       m5.large
metrics_name:  ['usage_idle','ebs1_cap_gib','ebs1_used_gib']
metrics_value: [80.2,10,7.6]
tags_name:     ['name','group']
tags_value:    ['sfg-prod-01','rtb']
复制代码

正如上文提到的,ClickHouse提供了大量的数组函数来直接处理数组中的数据。

例如,这里有一个快速查找缺少 "name"、"group"和 "owner"标签的任何VM的方法。 我们可以使用hasAll()函数,它可以验证第一个数组参数是否包含第二个参数所定义的数值子集。

代码语言:javascript
复制
WITH ['name', 'group', 'owner'] AS required_tags
SELECT distinct vm_id
FROM vm_data
WHERE NOT hasAll(tags_name, required_tags)
复制代码

注意到:WITH 来定义一个数组用于查询。 这是一个通用表表达式或CTE的例子。

CTEs通过从主查询中移除常量表达式来帮助降低查询的复杂性,是ClickHouse的最佳实践。我们将在其他例子中使用它们来保持事情的可读性。

ClickHouse的数组函数是相当多样的,涵盖了广泛的使用情况。下面是如何寻找 "group"标签值为 "rtb" 虚拟机的名称。正如你可能猜到的,indexOf()函数返回一个值的索引。我们可以用它来引用另一个数组中的值,这允许我们在tags_name和tags_value数组之间建立数值关系。

代码语言:javascript
复制
SELECT distinct vm_type
FROM vm_data
WHERE tags_value[indexOf(tags_name, 'group')] = 'rtb'

本文系转载,前往查看

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

本文系转载前往查看

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档