文章目录
- 创建 Bitmap 对象
- Bitmap 转换为整数数组
- 计算总数(去重)值
- 指定start, end 索引生成子 Bitmap
- 指定 start 索引和数量限制生成子 Bitmap
- 指定偏移量生成子 Bitmap
- 是否包含指定元素
- 两个 Bitmap 是否存在相同元素
- 一个是否为另一个 Bitmap 的子集
- 求最小值
- 求最大值
- And 求交集
- Or 求并集
- Andnot 求差集
- Xor 求并集元素减去交集元素
- 求交集元素个数
- 求并集元素个数
- 求差集元素个数
- 求异或元素个数
- 替换指定范围内的元素
Bitmap 类型说明
- ClickHouse中的Bitmap对象,本质上是聚合函数类型AggregateFunction(groupBitmap, UInt*)
- 使用 Bitmap 存储无符号整数,可以节省存储空间,无法直接查询Bitmap 中的数据,需要转换为数组才可以查看。
- 可以通过
groupBitmap(expr)
快速求去重后的总数,等价于count(distinct expr)
创建 Bitmap 对象
它有两种构造方法:
-
通过 bitmapBuild 将无符号整数数组转换为 Bitmap 对象
SELECT bitmapBuild([1,2,3]) AS res
-
使用聚合函数groupBitmapState创建Bitmap对象, 将无符号整数列转换为 Bitmap 对象。
SELECT groupBitmapState(UserID) AS res FROM hits_v1 where UserID IN ()
快速求去重后的数量:
# 等价于 count(distinct(UserID)) SELECT groupBitmap(UserID) AS res FROM hits_v1
输出如下:
Bitmap 转换为整数数组
bitmapBuild(array)
select bitmapBuild([1,2,3]) AS res, bitmapToArray(res) AS arr;################
┌─res─┬─arr─────┐
│ │ [1,2,3] │
└─────┴─────────┘
计算总数(去重)值
bitmapCardinality(bitmap)
数组中的元素为 Uint64 类型的
SELECT bitmapCardinality(bitmapBuild([1,2,3,4,5,5,5])) AS res;#################
┌─res─┐
│ 5 │
└─────┘
指定start, end 索引生成子 Bitmap
bitmapSubsetInRange(bitmap, range_start, range_end)
SELECT bitmapToArray(bitmapSubsetInRange(bitmapBuild([0,1,2,3,4,5,6,7,8]), toUInt32(1), toUInt32(3))) AS res;################
┌─res───┐
│ [1,2] │
└───────┘
指定 start 索引和数量限制生成子 Bitmap
bitmapSubsetLimit(bitmap, range_start, cardinality_limit)
SELECT bitmapToArray(bitmapSubsetLimit(bitmapBuild([0,1,2,3,4,5,6,7,8]), toUInt32(3), toUInt32(30))) AS res;################
┌─res───────────┐
│ [3,4,5,6,7,8] │
└───────────────┘
指定偏移量生成子 Bitmap
subBitmap(bitmap, offset, cardinality_limit)
偏移量从0开始
SELECT bitmapToArray(subBitmap(bitmapBuild([0,1,2,3,4,5,6,7,8]), toUInt32(3), toUInt32(30))) AS res;#######################
┌─res───────────┐
│ [3,4,5,6,7,8] │
└───────────────┘
是否包含指定元素
bitmapContains(bitmap, x)
包含返回1, 不包含返回0
SELECTbitmapContains(bitmapBuild([1, 3, 5, 7, 9]), toUInt32(3)) AS res1,bitmapContains(bitmapBuild([1, 3, 5, 7, 9]), toUInt32(4)) AS res2;#######################
┌─res1─┬─res2─┐
│ 1 │ 0 │
└──────┴──────┘
两个 Bitmap 是否存在相同元素
bitmapHasAny(bitmap1,bitmap2)
存在返回1, 不存在返回0
SELECT bitmapHasAny(bitmapBuild([1,2,3]), bitmapBuild([3,4,5])) as res1,bitmapHasAny(bitmapBuild([1,2,3]), bitmapBuild([4,5])) as res2;####################
┌─res1─┬─res2─┐
│ 1 │ 0 │
└──────┴──────┘
一个是否为另一个 Bitmap 的子集
bitmapHasAll(bitmap1,bitmap2)
SELECT bitmapHasAll(bitmapBuild([1,2,3]), bitmapBuild([2,3])) as res1,bitmapHasAll(bitmapBuild([1,2,3]), bitmapBuild([2,3,4])) as res2,bitmapHasAll(bitmapBuild([1,2,3]), bitmapBuild(emptyArrayUInt8())) as res3;#####################
┌─res1─┬─res2─┬─res3─┐
│ 1 │ 0 │ 1 │
└──────┴──────┴──────┘
求最小值
bitmapMin(bitmap)
数组为空返回0
SELECT bitmapMin(bitmapBuild([1,2,3])) as res1,bitmapMin(bitmapBuild(emptyArrayUInt8())) as res2;#############
┌─res1─┬─res2─┐
│ 1 │ 0 │
└──────┴──────┘
求最大值
bitmapMax(bitmap)
数组为空,返回0
SELECT bitmapMax(bitmapBuild([1,2,3])) as res1,bitmapMin(bitmapBuild(emptyArrayUInt8())) as res2;
###################
┌─res1─┬─res2─┐
│ 3 │ 0 │
└──────┴──────┘
And 求交集
bitmapAnd(bitmap1,bitmap2)
SELECT bitmapToArray(bitmapAnd(bitmapBuild([1,2,3]), bitmapBuild([2,3,4])
));
#################
┌─bitmapToArray(bitmapAnd(bitmapBuild([1, 2, 3]), bitmapBuild([2, 3, 4])))─┐
│ [2,3] │
└──────────────────────────────────────────────────────────────────────────┘
Or 求并集
bitmapOr(bitmap1,bitmap2)
SELECT bitmapToArray(bitmapOr(bitmapBuild([1,2,3]), bitmapBuild([2,3,4])
));
#################
┌─bitmapToArray(bitmapOr(bitmapBuild([1, 2, 3]), bitmapBuild([2, 3, 4])))─┐
│ [1,2,3,4] │
└─────────────────────────────────────────────────────────────────────────┘
Andnot 求差集
bitmapAndnot(bitmap1,bitmap2)
SELECT bitmapToArray(bitmapAndnot(bitmapBuild([1,2,3]), bitmapBuild([2,3,4])
));
#################
┌─bitmapToArray(bitmapAndnot(bitmapBuild([1, 2, 3]), bitmapBuild([2, 3, 4])))─┐
│ [1] │
└─────────────────────────────────────────────────────────────────────────────┘
Xor 求并集元素减去交集元素
bitmapXor(bitmap1,bitmap2)
SELECT bitmapToArray(bitmapXor(bitmapBuild([1,2,3]), bitmapBuild([2,3,4])
));###################
┌─bitmapToArray(bitmapXor(bitmapBuild([1, 2, 3]), bitmapBuild([2, 3, 4])))─┐
│ [1,4] │
└──────────────────────────────────────────────────────────────────────────┘
求交集元素个数
bitmapAndCardinality(bitmap1,bitmap2)
SELECT bitmapAndCardinality(bitmapBuild([1,2,3]), bitmapBuild([2,3,4])
);#############
┌─bitmapAndCardinality(bitmapBuild([1, 2, 3]), bitmapBuild([2, 3, 4]))─┐
│ 2 │
└──────────────────────────────────────────────────────────────────────┘
求并集元素个数
bitmapOrCardinality(bitmap1,bitmap2)
SELECT bitmapOrCardinality(bitmapBuild([1,2,3]), bitmapBuild([2,3,4])
);##################
┌─bitmapOrCardinality(bitmapBuild([1, 2, 3]), bitmapBuild([2, 3, 4]))─┐
│ 4 │
└─────────────────────────────────────────────────────────────────────┘
求差集元素个数
bitmapAndnotCardinality(bitmap1,bitmap2)
SELECT bitmapAndnotCardinality(bitmapBuild([1,2,3]), bitmapBuild([2,3,4])
);##################
┌─bitmapAndnotCardinality(bitmapBuild([1, 2, 3]), bitmapBuild([2, 3, 4]))─┐
│ 1 │
└─────────────────────────────────────────────────────────────────────────┘
求异或元素个数
bitmapXorCardinality(bitmap1,bitmap2)
SELECT bitmapXorCardinality(bitmapBuild([1,2,3]), bitmapBuild([2,3,4])
);##################
┌─bitmapXorCardinality(bitmapBuild([1, 2, 3]), bitmapBuild([2, 3, 4]))─┐
│ 2 │
└──────────────────────────────────────────────────────────────────────┘
替换指定范围内的元素
bitmapTransform(bitmap, from_array, to_array)
将Bitmap 中的 [5,999,2] 元素替换为 [2,888,20]
SELECT bitmapToArray(bitmapTransform(bitmapBuild([1,2,3,4,5,6,7,8,9,10]), [5,999,2], [2,888,20])
) as res;
#############
┌─res───────────────────┐
│ [1,3,4,6,7,8,9,10,20] │
└───────────────────────┘