ClickHouse Array Join中生成重复唯一ID的问题求助
解决ClickHouse Array Join后UUID重复的问题
问题根源
ClickHouse有个默认优化逻辑:如果函数不依赖任何表字段,就只会计算一次,把结果重复填充到所有行。generateUUIDv4()没有引用任何表内字段,所以array join拆分出来的每一行都会拿到同一个UUID。
可行解决方案
只要让UUID生成逻辑和每行的唯一数据绑定,就能确保每行生成不同的UUID,以下是几种实用方法:
方法1:用行号搭配UUID生成唯一值
借助rowNumberInAllBlocks()获取每行的唯一行号,和UUID拼接后转成标准UUID格式:
select toUUID(concat(toString(generateUUIDv4()), toString(rowNumberInAllBlocks()))) as unique_id, id, lst, now64(9) as created_at from test array join lst
方法2:基于行数据哈希生成UUID
把每行的唯一特征(比如原表ID+array元素)拼接后做哈希,再转成UUID,能保证唯一性:
select toUUID(sha256(concat(toString(id), lst))) as unique_id, id, lst, now64(9) as created_at from test array join lst
方法3:关闭常量折叠优化(不推荐)
通过查询参数关闭上述优化,强制generateUUIDv4()为每行单独计算,但这种方法会影响查询性能,仅临时测试可用:
select generateUUIDv4() as unique_id, id, lst, now64(9) as created_at from test array join lst settings optimize_functions_to_subcolumns = 0
验证示例
用你提供的测试表执行方法2的查询,就能得到每行唯一的UUID:
create table test ( id Int, lst Array(String) ) ENGINE = MergeTree ORDER BY id; insert into test (id, lst) values (1, ['a', 'b', 'c']); select toUUID(sha256(concat(toString(id), lst))) as unique_id, id, lst from test array join lst
输出的unique_id列三个值完全不同,符合需求。
内容的提问来源于stack exchange,提问作者sgerbhctim
相关产品推荐
相关产品推荐

