当前位置: 首页 > 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. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...