Clickhouse中的Array字段介绍
在 ClickHouse 中,Array(T)类型 是一种非常常用的 复合数据类型,用来存储 相同类型的元素的有序集合(即数组),比如:
-
一个用户有多个标签 →
Array(String),如['tag1', 'tag2', 'tag3'] -
一个订单包含多个商品 ID →
Array(UInt32),如[1001, 1002, 1003] -
一个设备上报了多个数值指标 →
Array(Float64)
1. 语法:
Array(T)
-
T 是数组中元素的类型,比如:-
Int32 -
String -
Float64 -
自定义类型,甚至是
Nested、Tuple等
-
-
Array(T) 表示一个元素类型为T的数组
2. 示例:建表时使用 Array 类型字段
CREATE TABLE example (
id UInt32,
tags Array(String), -- 字符串数组,如 ['a', 'b', 'c']
scores Array(Float64), -- 浮点数数组,如 [95.5, 88.0, 91.2]
counts Array(UInt32) -- 整数数组,如 [1, 2, 3]
) ENGINE = MergeTree()
ORDER BY id;
✅ 二、Array 类型常见用途
|
场景 |
说明 |
示例 |
|---|---|---|
|
标签 / 分类信息 |
一个实体有多个标签,如用户标签、商品类目 |
|
|
多值属性 |
比如一个订单有多个商品 ID、一个用户有多个设备 ID |
|
|
时间序列 / 指标数据 |
某个时间段内采集的多个数值 |
|
|
嵌套结构简化 |
在不用 |
比如 |
✅ 三、如何插入 Array 类型的数据?
在插入数据时,ClickHouse 支持用 方括号 [] 来直接表示数组。
✅ 示例:插入数据
INSERT INTO example (id, tags, scores, counts) VALUES
(1, ['tag1', 'tag2'], [95.5, 89.0], [1, 2]),
(2, ['tag3', 'tag4', 'tag5'], [91.0, 87.5, 90.0], [3, 4, 5]);
🔍 说明:
-
tags是一个字符串数组 -
scores是一个浮点数数组 -
counts是一个整数数组
✅ 四、如何查询 Array 类型字段?
1. 直接查询数组字段(原样展示)
SELECT id, tags FROM example;
输出类似:
┌─id─┬─tags───────────┐
│ 1 │ ['tag1','tag2']│
│ 2 │ ['tag3','tag4','tag5'] │
└────┴────────────────┘
2. 查询数组长度(元素个数):使用 length()函数
SELECT id, length(tags) AS tag_count FROM example;
输出:
┌─id─┬─tag_count─┐
│ 1 │ 2 │
│ 2 │ 3 │
└────┴───────────┘
3. 访问数组中的某个元素:使用 arrayElement(arr, index)或 arr[index]
索引从 1 开始(不是 0!)
SELECT
id,
tags[1] AS first_tag,
scores[2] AS second_score
FROM example;
输出:
┌─id─┬─first_tag─┬─second_score─┐
│ 1 │ tag1 │ 89.0 │
│ 2 │ tag3 │ 87.5 │
└────┴───────────┴──────────────┘
✅ 五、常用 Array 函数(ClickHouse 提供了很多!)
|
函数 |
说明 |
示例 |
|---|---|---|
|
|
返回数组长度(元素个数) |
|
|
|
获取第 n 个元素(从 1 开始) |
|
|
|
判断数组是否包含某个值 |
|
|
|
将数组展开为多行(常用于展开数组后关联查询) |
详见下文 |
|
|
拼接多个数组 |
|
|
|
是否包含某个值(同 has) | |
|
|
对数组排序 |
|
|
|
去重 |
|
|
|
求数组数值元素之和(仅数值类型) |
|
|
|
平均值 |
仅适用于数值类型 |
|
|
最小值 / 最大值 |
✅ 六、高级用法:arrayJoin(数组展开为多行)
如果你想把一个数组字段的每个元素拆成 多行(一行变多行,每个元素一行),可以使用 arrayJoin函数。
✅ 示例:
SELECT
id,
arrayJoin(tags) AS single_tag
FROM example;
假设原数据:
id | tags
---|-----------
1 | ['a', 'b']
2 | ['x', 'y', 'z']
输出结果为:
┌─id─┬─single_tag─┐
│ 1 │ a │
│ 1 │ b │
│ 2 │ x │
│ 2 │ y │
│ 2 │ z │
└────┴────────────┘
🔍 用途:
-
用于数组展开后与其他表做 JOIN
-
用于分析数组中的每个元素
-
用于生成多行明细
✅ 七、在 WHERE 子句中过滤数组
你可以使用以下方式对数组字段进行过滤:
1. 判断数组是否包含某个值:has(array, value)
SELECT * FROM example WHERE has(tags, 'tag1');
2. 判断数组长度:length(array) > 0
SELECT * FROM example WHERE length(tags) > 0;
3. 结合 AND / OR 复杂条件
✅ 八、在 ORDER BY / GROUP BY 中使用 Array
-
GROUP BY数组字段本身通常无意义(数组是集合,不是标量) -
但你可以:
-
使用
arrayJoin展开后再 GROUP BY -
或者使用
arrayReduce等聚合函数对数组内容做聚合
-
✅ 九、Array 与 JSON 的对比
|
特性 |
Array(T)(ClickHouse) |
JSON(如 String 类型存储 JSON 数组) |
|---|---|---|
|
类型安全 |
✅ 是,数组元素类型固定为 T |
❌ 否,JSON 是文本,类型不安全 |
|
查询效率 |
✅ 高,ClickHouse 对 Array 有原生优化 |
❌ 较低,需用 JSON 函数解析 |
|
灵活性 |
❌ 元素类型固定 |
✅ 可存储任意结构 |
|
推荐使用场景 |
明确知道是同类型元素的集合,如标签、数值列表 |
存储异构、灵活结构,如配置、元数据 |
✅ 十、总结:ClickHouse 的 Array 类型
|
项目 |
说明 |
|---|---|
|
定义方式 |
|
|
用途 |
存储一组相同类型的值,如标签、列表、多值属性等 |
|
插入方式 |
直接用 |
|
查询支持 |
提供丰富函数: |
|
展开数组 |
使用 |
|
性能 |
ClickHouse 对 Array 类型有原生优化,查询效率高 |
|
常见场景 |
用户标签、商品 SKU 列表、日志中的多个数值、维度展开等 |
✅ 附:建表示例 + 插入 + 查询 综合案例
-- 1. 建表
CREATE TABLE user_tags (
user_id UInt32,
tags Array(String),
scores Array(Float64)
) ENGINE = MergeTree()
ORDER BY user_id;
-- 2. 插入数据
INSERT INTO user_tags VALUES
(1, ['music', 'sports'], [9.5, 8.0]),
(2, ['books', 'travel', 'food'], [9.0, 9.5, 8.5]),
(3, ['tech'], [10.0]);
-- 3. 查询
SELECT
user_id,
tags,
length(tags) AS tag_count,
tags[1] AS first_tag
FROM user_tags;
-- 4. 展开数组(每个标签一行)
SELECT
user_id,
arrayJoin(tags) AS tag
FROM user_tags;
更多推荐

所有评论(0)