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

news2024/11/15 10:15:53

文章目录

    • 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 definition

CREATE 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;
-- 查询并求平均年龄
SELECT
	title,
	avg(actor.age) AS avg_age
FROM
	movies 
	ARRAY JOIN actors AS actor
GROUP BY
	title
ORDER BY
	title;
  • 第一条SQL的执行结果如下:
    在这里插入图片描述
  • 这里看下使用Nested类型创建之后表的DDL,可以发现与Tuple没啥区别
-- `default`.movies definition

CREATE 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 definition

DROP 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如下:
SELECT
	time_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
FROM
	index_cycle_security ARRAY JOIN approach_index
where time_stamp = '2023-05-09 14:05:52'
order by time_stamp
  • 查询时,使用ARRAY JOIN将嵌套结构分成一个个列,查询结果如下:
    在这里插入图片描述
  • 我也可以按照时间粒度聚合(使用toStartOfInterval),之后求平均值,SQL如下:
SELECT
	toStartOfInterval(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
FROM
	index_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
  • 查询结果如下(由于都是测试数据,结果一样了,结构是可以看的):
    在这里插入图片描述
  • 看到最后的小伙伴,欢迎评论交流,给个点赞也行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/508985.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RFID技术在智能制造领域的发展

RFID技术在智能制造领域的发展 RFID技术是构建智能制造的基础,自RFID技术普及以来,工业产线、零售、物流、交通、医疗、制造等领域,都能看到到RFID应用的身影。就智能制造领域来说,通过RFID技术可以帮助制造企业开展各项市场需求…

shell函数数组

shell函数数组 数组的表达方式 (30 20 10 60 50 40) #数组0 1 2 3 4 5 #下标下标从0开始,中间可以断开 一: 数组的定义方法 方法一 数组名(value0 value1 value2 ...)方法二 数组名&#xff08…

网络路径下倾斜模型生产流程-模型s3c化

网络路径下倾斜模型生产流程-模型s3c化 将osgb模型处理文件拷贝到osgb模型文件夹下 在osgb模型文件夹下,新建与工程同名文件夹,然后将原文件夹下所有文件拷贝到YNPE27文件夹下, E:\YNPE27\CC\YNPE27\Productions\Production_2\YNPE27 打开o…

Python3,5行代码,Chatxxx能对PDF文件进行旋转、提取、合并等一系列操作,看了这篇,80岁老奶奶走路都不扶墙了。

ChatPDF的妙用 1、引言2、代码实战2.1 原理2.2 安装2.2 示例2.2.1 创建PDF文件2.2.2 旋转PDF文件2.2.3 拆分PDF文件2.2.4 合并PDF文件2.2.5 提取PDF文件内容 3、总结 1、引言 小屌丝:鱼哥,最近干啥了? 小鱼:最近? 你指…

基于MATLAB的无人机遥感数据预处理与农林植被性状估算

在新一轮互联网信息技术大发展的现今,无人机、大数据、人工智能、物联网等新兴技术在各行各业都处于大爆发的前夜。为了将人工智能方法引入农业生产领域。首先在种植、养护等生产作业环节,逐步摆脱人力依赖;在施肥灌溉环节构建智慧节能系统&a…

如何使用CSDN的Markdown编辑器?

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

【C++的类与对象(下)】

目录 一、细说构造函数1.1初始化列表的引入1.2初始化列表1.2关键字explicit 二、static成员2.1static成员的特性2.2题目:实现一个类,计算程序中创建出了多少个类对象2.3题目:设计一个类 只能再栈上或者堆上创建 一、细说构造函数 1.1初始化列…

【A、B、C、D、E类IP地址划分依据,你都会吗?】

IP 地址的格式:IP 地址 网络地址 主机地址 如果 IP 进行了子网划分: 则IP地址网络地址子网地址主机地址 网络地址是互联网上的节点在网络中具有的逻辑地址。MAC 地址,处于数据链 路层,IP 地址处于网络层,端口号处…

考研数据结构--树和二叉树(1)

树和二叉树 文章目录 树和二叉树树定义形式化定义递归定义 树的(逻辑)表示树形表示法文氏图表示法凹入表示法括号表示法 树的基本术语1. 结点的度与树的度2. 分支结点与叶结点3. 路径与路径长度4. 孩子结点、双亲结点和兄弟结点5. 子孙结点和祖先结点6. …

搭建web服务器

目录标题 搭建web服务器,并显示Redhat测试界面linux主机作为服务器部署web服务程序 Apache http server(httpd)当前主机启动该服务程序关闭防火墙和selinux 客户端 搭建网站创建自拟定网页文件linux主机作为服务器部署web服务器程序当前主机启…

Qt配置glfw库(Windows)

文章目录 一、下载glfw二、配置2.1、创建Qt工程2.2、移植库文件2.3、导入库到Qt工程2.4、添加OpenGL库2.5、测试代码 一、下载glfw glfw官网下载:https://www.glfw.org/download.html 下载之后,解压如下: 二、配置 2.1、创建Qt工程 创建一…

优质且免费的10个在线图片设计网站!

1.即时设计 即时设计资源社区是一个开源式免费商用图片素材网站,将社交、作品浏览和模板复用融合在一起。它内置了来自国内外优秀设计系统如TDesign、Arco Design、Ant Design和Material Design等的海量设计规范,以及超过3000个UI组件库和每月更新的上百…

远程桌面连接是什么?如何开启远程桌面连接详细教程

远程桌面连接是一种非常方便的技术,它允许用户通过互联网在不同的计算机之间共享资源和访问数据。目前这个技术已经广泛地应用于企业、教育、医疗和其他领域,使得人们能够更高效地工作和学习。 这篇文章,我将解释远程桌面连接是什么&#xf…

leecode111——二叉树最短路径

递归三部曲: 最小深度是从根节点到最近叶子节点的最短路径上的节点数量 (1)确定参数和返回值, 参数为传入根节点,再根据此遍历左右左右树的节点。返回最短路径,即int类型。 (2)确…

第4章 静态网站部署

第4章 静态网站部署 Nginx是一个HTTP的web服务器,可以将服务器上的静态文件(如HTML、图片等)通过HTTP协议返回给浏览器客户端 4.1 案例:将ace-master这个静态网站部署到Nginx服务器上 4.1.1 通过Xftp将ace-master到linux服务器…

深入探究HDFS:高可靠、高可扩展、高吞吐量的分布式文件系统【上进小菜猪大数据系列】

上进小菜猪,沈工大软件工程专业,爱好敲代码,持续输出干货。 引言 在当今数据时代,数据的存储和处理已经成为了各行各业的一个关键问题。尤其是在大数据领域,海量数据的存储和处理已经成为了一个不可避免的问题。为了应…

Sharding-JDBC之广播表(公共表)

目录 一、简介二、maven依赖三、数据库3.1、创建数据库3.2、创建表 四、配置(二选一)4.1、properties配置4.2、yml配置 五、实现5.1、持久层5.2、持久层5.3、服务层5.4、测试类5.4.1、保存数据5.4.2、查询广播表5.4.3、查询订单数据(关联广播…

selenium——unittest框架

目录 一、unittest框架基本介绍二、unittest框架解析三、unittest框架使用方法1.测试固件2.测试套件3.用例的执行顺序4.忽略测试用例中的方法5.unittest断言6.HTML报告生成 一、unittest框架基本介绍 在进行selenium IDE脚本录制导出的脚本中,我们发现其中多了很多…

第十三章_Redis中的BigKey

MoreKey案例 大批量往redis里面插入2000W测试数据key Linux Bash下面执行&#xff0c;插入100W # 生成100W条redis批量设置kv的语句(keykn,valuevn)写入到/tmp目录下的redisTest.txt文件中 for((i1;i<100*10000;i)); do echo "set k$i v$i" >> /tmp/redi…

使用Eclipse +SpotBugs 检测代码弱点

文章目录 SpotBugs 插件的安装SpotBugs 的使用弱点扫描弱点查看的视图SpotBugs 是分析Java代码弱点的静态分析工具,SpotBugs提供了Eclipse的插件使用方式,在Eclipse 中安装插件之后就可以坚持Java代码的弱点了。 SpotBugs 插件的安装 SpotBugs 的插件安装主要有两种方式 在插…