当前位置: 首页 > news >正文

clickhouse的嵌套数据结构Tuple、Array与Nested类型介绍和使用示例

文章目录

    • Tuple类型
    • Array类型
    • Nested类型
    • 使用示例
      • 单独使用Tuple
      • 数组嵌套 Array(Tuple)
      • Nested类型
    • 生产使用:分组查询

Tuple类型

  • TupleClickHouse数据库中的一种数据类型,它允许在一个字段中存储由不同数据类型组成的元组(tuple)。
  • 元组可以包含任意数量的值,并且每个值可以是不同的数据类型,如intfloatstringdate等。
  • 例如,以下是一个clickhouse Tuple类型的例子:
    (1, 'John', 12.5, Date('2021-01-01'))

该元组包含四个值,分别是整数1,字符串’John’,浮点数12.5和日期型数据’2021-01-01’。这些值可以通过索引或字段名来访问。

  • Tuple类型可以用于存储数据结构复杂的数据,如JSONXML数据。
  • 此外,clickhouseTuple类型还可以用于支持复杂的查询和分析操作,例如在SELECT语句中使用子查询或嵌套查询,或在JOIN运算中使用多个字段来匹配复杂的条件等。

Array类型

  • Array类型表示一个包含多个相同类型元素的数组,可以通过索引访问其中的元素
  • Array类型就不详细讲了,之前写过一篇文章,有兴趣的可以点击看下
  • 当需要处理数组结构时,可以使用Array类型,而当需要处理更复杂的数据结构时,可以使用Nested类型
  • 通常,Nested类型比Array类型更加灵活,但是在性能方面可能会稍微慢一些。

Nested类型

  • ClickHouse中的Nested类型指的是复杂数据类型,它允许将多个数据类型组合成一种数据类型
  • Nested类型支持结构化数组、嵌套映射(Map)和嵌套集合(Set),可以方便地处理非标量类型的数据
  • Nested类型可以用于存储和查询具有嵌套结构的数据,例如JSONXML格式的数据。它能够支持高效的查询和聚合操作,如对嵌套数组进行平均、求和、最大、最小等操作,对于分析大量结构化数据非常有效。
  • 在使用Nested类型时,需要注意其与普通数据类型的不同之处,在查询语句中需要使用嵌套函数或语法。同时需要进行适当的数据类型转换和格式化操作,以确保数据的准确性和一致性。

使用示例

单独使用Tuple

  • 具体SQL如下,包括建表、插入数据、查询
  • 需要注意的点:
    • 字段为Tuple类型时,里面要直接是数据类型,即tuple_col Tuple(String, UInt8)
    • 插入时,只能是单个Tuple数据,不能为复数个,即(1, ('Alice', 20))
-- 建表
drop table if exists my_table_tuple;
CREATE TABLE my_table_tuple (id Int32,tuple_col Tuple(String, UInt8)
) ENGINE = MergeTree ORDER BY id;-- 插入数据
INSERT INTO my_table_tuple VALUES
(1, ('Alice',  20)),(2, ('Bob',  35)),(3, ('Charlie',  40)),(4, ('David',  45));-- 查询数据
SELECT * FROM my_table_tuple;
SELECT id, tuple_col.1 as name, tuple_col.2 as age  FROM my_table_tuple;
-- 注意,Tuple无法使用ARRAY JOIN,会执行报错
SELECT * FROM my_table_tuple ARRAY JOIN tuple_col;
  • 下面2个截图,为上面2个可以执行成功的SQL的查询结果
    在这里插入图片描述在这里插入图片描述

数组嵌套 Array(Tuple)

  • 数组类型,数组内为Tuple
  • 具体SQL如下,包括建表、插入数据、查询
  • 需要注意的点:
    • 此时的Tuple允许定义字段名称,即Tuple( name String, age UInt8)
    • 插入时,可以是单个Tuple数据,也可以是复数个,即(1, ['Alice','Bob'], [20, 35])
    • 需要注意的是,不能像单个Tuple类型使用时写的('Bob', 35),而是每个Tuple嵌套类型里的字段,都是一个数组,要作为数组插入
    • 插入时,行和行之间的属性的个数可以不一致 ,但是当前行的Nested类型中的字段对应的数组内的数量要一致
-- 新建表
DROP table if exists  my_table_array_tuple;
CREATE TABLE my_table_array_tuple (id Int32,array_tuple Array(Tuple( name String, age UInt8))
) ENGINE = MergeTree ORDER BY id;-- 插入数据
INSERT INTO my_table_array_tuple VALUES
(1, ['Alice','Bob'], [20, 35]),
(2, ['Charlie', 'David', 'Tom'], [40, 45, 34]);-- 这个插入数据的SQL执行失败,无法类似这样插入
INSERT INTO my_table_array_tuple VALUES
(3, [('Alice',  20),('Bob',  35)]),
(4, [('Charlie',  40),('David',  45)]);-- 查询
SELECT * FROM my_table_array_tuple;
SELECT id, array_tuple.name, array_tuple.age  FROM my_table_array_tuple;
SELECT * FROM my_table_array_tuple ARRAY JOIN array_tuple;
  • 上面三个查询SQL的查询结果,截图如下,其中前两个SQL执行结果一致
    在这里插入图片描述
  • 前两个查询结果为啥一致,为什么插入的时候是插入多个数组,看下create table执行后的表ddl就很明确了
-- `default`.my_table_array_tuple definitionCREATE TABLE default.my_table_array_tuple
(`id` Int32,`array_tuple.name` Array(String),`array_tuple.age` Array(UInt8)
)
ENGINE = MergeTree
ORDER BY id
SETTINGS index_granularity = 8192;
  • 第三条SQL是使用了ARRAY JOIN,分行展开们我们需要的样子
    在这里插入图片描述

Nested类型

  • 类似Tuple,但是不一样,Tuple一次只能插入一个元祖,但Nested类型既可以插入一个Nested类型数据,也可以插入多个,用起来感觉类似Array(Tuple)
  • 具体SQL如下,包括建表、插入数据、查询
  • 需要注意的点:
    • Array(Tuple)一样,此时的Nested也允许定义字段名称,即Nested( name String, age UInt8)
    • 插入数据时,也需要遵循“嵌套类型里的每一个字段对应一个数组”
    • 插入数据时,也需要遵循“单条记录内,嵌套类型每一个字段对应的值数量相同”,不同记录数量没有要求
-- 创建表
drop table if exists movies;
CREATE TABLE movies (title String,actors Nested(name String,age UInt8)
) ENGINE = MergeTree()
ORDER BY title;
-- 插入数据
INSERT INTO movies VALUES('Interstellar', ['Matthew McConaughey', 'Anne Hathaway'], [50, 38]);
INSERT INTO movies VALUES('The Dark Knight', ['Christian Bale', 'Heath Ledger', 'Aaron Eckhart'], [47, 28, 52]);
-- 查询
SELECT * FROM movies;
SELECT * FROM movies ARRAY JOIN actors;
-- 查询并求平均年龄
SELECTtitle,avg(actor.age) AS avg_age
FROMmovies ARRAY JOIN actors AS actor
GROUP BYtitle
ORDER BYtitle;
  • 第一条SQL的执行结果如下:
    在这里插入图片描述
  • 这里看下使用Nested类型创建之后表的DDL,可以发现与Tuple没啥区别
-- `default`.movies definitionCREATE TABLE default.movies
(`title` String,`actors.name` Array(String),`actors.age` Array(UInt8)
)
ENGINE = MergeTree
ORDER BY title
SETTINGS index_granularity = 8192;
  • 第二条SQL也是使用了ARRAY JOIN,执行结果如下:
    在这里插入图片描述
  • 第三条SQL,是查询评价年龄,是对嵌套类型里的一个字段进行运算。除了求平均,其他的函数运算也可以,聚合分组也可以
    -

生产使用:分组查询

  • 我们的安全指标表,需要存储道路级别安全指标和进口级别安全指标,建表语句(部分)如下:
-- radar.index_cycle_security definitionDROP table if exists radar.index_cycle_security;
CREATE TABLE radar.index_cycle_security
(`time_stamp` DateTime COMMENT '时间',`intersection_number` Int32 COMMENT '交叉口编号',`safety_factor` Float64 COMMENT '安全系数(根据下面4个安全评价参数加权计算,只计算整个路口的)',`phase_clearance_rate` Float64 COMMENT '相位清空率(路口)',`pedestrian_time_guarantee_rate` Float64 COMMENT '行人过街时间保障率(路口)',`pedestrian_illegal_rate` Float64 COMMENT '行人闯红灯违法率(路口)',`traffic_conflict` Int16 COMMENT '交通冲突次数(车道/方向)',`approach_index` Array(Tuple(`approach` String,`pedestrian_time_guarantee_rate` Float64,`pedestrian_illegal_rate` Float64 ))
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(time_stamp)
PRIMARY KEY time_stamp
ORDER BY (time_stamp, intersection_number)
SETTINGS index_granularity = 8192,old_parts_lifetime = 300,max_suspicious_broken_parts = 1000;
-- 显示表结构
desc radar.index_cycle_security;
  • 现在我的业务查询需求,需要根据进口按列返回,SQL如下:
SELECTtime_stamp ,approach_index.approach as approach, approach_index.pedestrian_time_guarantee_rate as pedestrian_time_guarantee_rate,approach_index.pedestrian_illegal_rate as pedestrian_illegal_rate
FROMindex_cycle_security ARRAY JOIN approach_index
where time_stamp = '2023-05-09 14:05:52'
order by time_stamp
  • 查询时,使用ARRAY JOIN将嵌套结构分成一个个列,查询结果如下:
    在这里插入图片描述
  • 我也可以按照时间粒度聚合(使用toStartOfInterval),之后求平均值,SQL如下:
SELECTtoStartOfInterval(time_stamp , INTERVAL 1 HOUR) as time_stamp2 ,approach_index.approach as approach, round(avg(approach_index.pedestrian_time_guarantee_rate), 2) as pedestrianTimeGuaranteeRate,round(avg(approach_index.pedestrian_illegal_rate), 2) as pedestrianIllegalRate
FROMindex_cycle_security ARRAY JOIN approach_index
where time_stamp > '2023-05-09 14:05:52'
GROUP BY time_stamp2, approach
order by time_stamp2 
limit 0,20
  • 查询结果如下(由于都是测试数据,结果一样了,结构是可以看的):
    在这里插入图片描述
  • 看到最后的小伙伴,欢迎评论交流,给个点赞也行

相关文章:

clickhouse的嵌套数据结构Tuple、Array与Nested类型介绍和使用示例

文章目录 Tuple类型Array类型Nested类型使用示例单独使用Tuple数组嵌套 Array(Tuple)Nested类型 生产使用:分组查询 Tuple类型 Tuple是ClickHouse数据库中的一种数据类型,它允许在一个字段中存储由不同数据类型组成的元组(tuple)。元组可以包含任意数量…...

人脸修复增强调研

Real-ESRGAN 工程地址:https://github.com/xinntao/Real-ESRGAN 效果: 人脸增强部分,调用的GFPGAN. GFPGAN 工程地址:https://github.com/TencentARC/GFPGAN 论文效果: BasicSR-ESRGAN: 项目地址&a…...

【Java】继承和多态

文章目录 一、继承1.继承的例子(is-a)2.组合的例子(has-a) 二、多态1.重写2.重载 三、继承的语法四、继承的注意事项1.初始化的顺序:2.super关键字 五、继承访问限定符六、多态实现方式七、多态的理解注意事项&#xf…...

ThingsBoard集群部署之k8s

1、概述 今天终于有时间去搞这个啦,拖了很久了,一直没时间,因为我本地没有那么多机器资源,开虚拟机不够,如果租用阿里云服务器,需要有充值的时间,因为这个费用是按小时付费,需要有连贯的时间来搞才行,今天恰好有时间,就开始搞了,弄成功搞出来了,特地写博客记录下来…...

【Gorm】如何在 GORM 中实现模型之间的关联?

文章目录 关联1、Belongs To(属于)2、Has One(拥有一个)3、Has Many(拥有多个)4、Many To Many(多对多) 关联 ​ 当涉及到 ORM(Object-Relational Mapping)的…...

Linux危险命令

rm -rf 命令 该命令可能导致不可恢复的系统崩坏。 rm -rf / #强制删除根目录下所有东西。rm -rf * #强制删除当前目录的所有文件。rm -rf . #强制删除当前文件夹及其子文件夹。fork 炸弹 :() { :|:& };:不太好理解可以转换成 bomb() {bomb|bomb& }; bomb一旦执行…...

FPGA入门系列13--异步串口通信

文章简介 本系列文章主要针对FPGA初学者编写,包括FPGA的模块书写、基础语法、状态机、RAM、UART、SPI、VGA、以及功能验证等。将每一个知识点作为一个章节进行讲解,旨在更快速的提升初学者在FPGA开发方面的能力,每一个章节中都有针对性的代码…...

k8s基础4——deployment控制器、应用部署、升级、回滚、水平扩容缩容

文章目录 一、基本介绍二、应用程序生命周期2.1 部署应用2.2 应用升级2.2.1 修改YAML文件升级(交互式)2.2.2 命令指定镜像版本升级(免交互式)2.2.3 调用vim升级 2.3 滚动升级2.3.1 升级流程 2.4 应用回滚2.4.1 查看历史发布版本2.…...

动态规划算法——40道leetcode实例入门到熟练

目录 t0.解题五部曲1.基础入门题目1.509. 斐波那契数2.70. 爬楼梯3.746. 使用最小花费爬楼梯4.62. 不同路径5.63. 不同路径 II6.343. 整数拆分7.96. 不同的二叉搜索树 2.背包问题1.01背包(二维数组实现)2.01背包(滚动数组实现)1.4…...

Nmap入门到高级【第十一章】

预计更新第一章. Python 简介 Python 简介和历史Python 特点和优势安装 Python 第二章. 变量和数据类型 变量和标识符基本数据类型:数字、字符串、布尔值等字符串操作列表、元组和字典 第三章. 控制语句和函数 分支结构:if/else 语句循环结构&#…...

配置本地Angular环境并使用VsCode调试Angular前端项目

配置本地Angular环境并使用VsCode调试Angular前端项目 配置本地Angular环境部署Node.Js本地环境配置一下环境变量 使用vscode调试Angular安装vscode 配置本地Angular环境 部署Node.Js本地环境 1 从官网下载node.js, 本文为(v16.13.0) 下载地址: https://nodejs.org/dist/v16.…...

100ASK_全志V853-PRO开发板支持人形检测和人脸识别

1.前言 V853 芯片内置一颗 NPU核,其处理性能为最大 1 TOPS 并有 128KB 内部高速缓存用于高速数据交换,支持 OpenCL、OpenVX、android NN 与 ONNX 的 API 调用,同时也支持导入大量常用的深度学习模型。本章提供一个例程,展示如何使…...

简单实现基于UDP与TCP的回显服务器

目录 前言UDP 版的回显服务器需要用到的 api服务端客户端UDP 版本的字典客户端和字典服务器 TCP 版的回显服务器需要用到的 api服务器客户端对服务器进行改进(使用线程池)TCP 版本的字典客户端和字典服务器 前言 我们写网络程序, 主要编写的是应用层代码. 真正要发送这个数据,…...

家用洗地机有什么推荐的吗?家用洗地机哪款好

洗地机是创新、高效的清洁工具,其具有高性能的清洁能力和卓越的操作体验。与传统的清洁工具相比,洗地机可以迅速而彻底地打扫地面,降低清洁时间和人力成本,让我们在工作之余不用花费大量的时间和精力去打扫卫生,下面就…...

深度学习与文本聚类:一篇全面的介绍与实践指南

❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️ 👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…...

AP5153 线性降压恒流驱动芯片 2.5A

AP5153 是一种 PWM 调光的、低压 差的 LED 线性降压恒流驱动器。 AP5153 仅需要外接一个电阻和一个 NMOS 管就可以构成一个完整的 LED 恒 流驱动电路, 调节该外接电阻就可以调节 输出电流,输出电流可调范围为 20mA 到 3.0A。 AP5153 还可以通过在 DIM…...

Unity物理系统脚本编程(下)

一、修改物理材质 Unity对物体表面材料的性质做了件化处理,仅有5种常用属性: Dynamic Friction(动态摩擦系数)Static Friction(静态摩擦系数)Bounciness(弹性系数)Friction Combine…...

容器技术的发展

容器技术的发展 近年来,随着计算机硬件、网络以及云计算等技术的迅速发展,云原生的概念也越来越受到业界人士的广泛关注,越来越多的应用场景开始拥抱云原生,其中容器技术的发展起着至关重要的作用。本章将介绍容器技术的基础知识…...

Python Flask request中常见存储参数的介绍

Python Flask request中常见存储参数的介绍 首先从flask模块中导入请求对象: from flask import requestrequest.form 通过method属性可以操作当前请求方法,通过使用form属性处理表单数据(本质也是得到一个字典,如果传输的是字…...

php+vue网盘系统的设计与实现

该网盘系统的开发和设计根据用户的实际情况出发,对系统的需求进行了详细的分析,然后进行系统的整体设计,最后通过测试使得系统设计的更加完整,可以实现系统中所有的功能,在开始编写论文之前亲自到图书馆借阅php书籍&am…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...

PHP和Node.js哪个更爽?

先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦&#xff0…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

背包问题双雄:01 背包与完全背包详解(Java 实现)

一、背包问题概述 背包问题是动态规划领域的经典问题&#xff0c;其核心在于如何在有限容量的背包中选择物品&#xff0c;使得总价值最大化。根据物品选择规则的不同&#xff0c;主要分为两类&#xff1a; 01 背包&#xff1a;每件物品最多选 1 次&#xff08;选或不选&#…...