clickhouse位图bitmap函数原创
ClickHouse位图bitmap函数在数据分析及开发中应用十分广泛,Bitmap函数相对略微复杂。Bitmap是大数据里面常见的数据结构,简单来说就是按位存储,为了解决在去重场景里面大数据量存储问题
位图函数用于对两个位图对象进行计算,对于任何一个位图函数,它都将返回一个位图对象,例如and,or,xor,not等。
数组转为位图,天然去重。再 [交、并、差] 运算的数据分析中有很大优势。
具体可在官网查看,这里列举部分常用函数进行示例学习。
# 1. 常用基本函数
用途 | 函数 | 备注 |
---|---|---|
构建bitmap | bitmapBuild(array) | |
bitmap转数组 | bitmapToArray(bitmap) | |
交集 | bitmapAnd(bitmap1, bitmap2) | 返回一个新的位图对象 |
并集 | bitmapOr(bitmap1, bitmap2) | 返回一个新的位图对象 |
差集 | bitmapAndnot(bitmap1, bitmap2) | 返回一个新的位图对象 |
计算位图基数 | bitmapCardinality(bitmap) | |
交集数 | bitmapAndCardinality(bitmap1, bitmap2) | |
并集数 | bitmapOrCardinality(bitmap1, bitmap2) | |
差集数 | bitmapAndnotCardinality(bitmap1, bitmap2) |
# 2. 聚合函数
- 上述的基本还是一次只能进行两个bitmap的运算,想要计算一组bitmap,可以使用聚合函数。
用途 | 函数 | 备注 |
---|---|---|
交集 | groupBitmapAndState(expr) | 返回一个新的位图对象 |
并集 | groupBitmapOrState(expr) | 返回一个新的位图对象 |
交集数 | groupBitmapAnd(expr) | |
并集数 | groupBitmapOr(expr) |
# 3. bitmap表创建
- 具体创建32位还是64位的位图,取决于总数据量的多少。
create table if not exists test.test_bitmap
(
`create_date` Date COMMENT '数据时间'
, `id` String COMMENT 'ID'
, `bitmap` AggregateFunction(groupBitmap, UInt64) COMMENT '位图'
)
ENGINE = MergeTree()
ORDER BY (create_date, id)
PARTITION (create_date)
SETTINGS index_granularity = 1
COMMENT 'bitmap测试表'
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 4. bitmap写入
如果你的数据是Int64类型,恭喜你,可以直接聚合为bitmap,并且计算完可以导出你的结果。
如果你的数据是String类型,可以先转化为crc64:CRC64(),再聚合为bitmap,优点是可以支持字符串类型的交并差运算。缺点是数据不能回滚,只能计算交、并、差数据量。
--单个标签导入
insert into test.test_bitmap
select create_date, id, groupBitmapState(CRC64(test_id))
from test.test_id_table
where create_date = today()
and id = 'hehe';
insert into test.test_bitmap
select create_date, id, groupBitmapState(CRC64(test_id))
from test.test_id_table
where create_date = today()
and id = 'haha';
--多个标签导入
insert into test.test_bitmap
select create_date, id, groupBitmapState(CRC64(test_id))
from test.test_id_table
where create_date = today()
and id in ('hehe2', 'haha2', 'heih2')
group by create_date, id;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 5. bitmap计算
-- 例1:计算两个bitmap的交集数
-- 方法1
select bitmapAndCardinality(a.bitmap, b.bitmap)
from
(select bitmap from test.test_bitmap where create_date = today() and id = 'hehe')a
, (select bitmap from test.test_bitmap where create_date = today() and id = 'haha')b;
-- 方法2
select groupBitmapAnd(bitmap)
from test.test_bitmap
where create_date = today() and id in ('hehe', 'haha');
-- 例2:计算多个bitmap的交集数
select groupBitmapAnd(bitmap)
from test.test_bitmap
where create_date = today() and id like '%h%';
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 02
- 2025-03-28拍婚纱照 原创04-02
- 03
- 2024-04-05的晚上 原创04-01