KingbaseES roaringbitmap扩展介绍
关键字
KingbaseES、roaringbitmap、大数据量、支持索引、人大金仓
问题描述
业务应用场景中常有通过标签进行筛选查询的功能,在数据量较大且标签值较多的场景下,数据容量会占用很多,性能也会较差,如何高效快速且不占用太多数据容量的情况下进行目标资源筛查,成为业务管理优化的不变话题。
roaringbitmap 在业务中常用来存储用户的属性标签,可增删改查这些属性标签以及根据这些存储的用户的标签,通过并集、交集等方法来筛选出特定的用户,以达到超大规模属性数据的精准快速查找,既提升了性能,同时也能降低存储空间,是大数据分析场景下极佳的应用实践。
Roaring Bitmap算法介绍
背景
为了解决位图稀疏存储浪费空间的问题,出现了很多稀疏位图的压缩方法,Roaring Bitmap就是其中的一种。Roaring Bitmap(高效压缩位图)是一种高效的Bitmap压缩算法,常用于标签筛选、去重、时间序列等计算中。
原理
Roaring Bitmap算法是将32位的INT类型数据划分为高16位和低16位两部分,其中高16位作为桶的编号,共划分出2^16个桶,即最多可能有2^16=65536个桶,相关论文内称为container。然后再将低 16 位值存放在相应的 Container 中(存储时如果找不到就会新建一个)。
Container的类型
①ArrayContainer(数组容器)
在创建一个新Container时,如果只插入一个元素,Roaring Bitmap默认会用ArrayContainer来存储。其中每一个元素的类型为short int 占两字节。当ArrayContainer的容量超过4096后,会自动转成BitmapContainer。
关于4096这个阈值,低于4096时,ArrayContainer比较省空间,高于它时,BitmapContainer比较省空间。ArrayContainer用来存储稀疏数据,BitmapContainer用来存储稠密数据,这样可以最大限度地避免内存浪费。
②BitmapContainer
底层实现为位图。这种Container使用long[]存储位图数据。我们知道,每个Container处理16位整形的数据,也就是0~65535,因此根据位图的原理,需要65536个bit来存储数据,每个比特位用1来表示有,用0来表示无,每个long有64位,因此需要1024个long来提供65536个比特。
这就意味着,不管一个BitmapContainer值在构建时就会初始化长度为1024的long[]。这就意味着,不管一个BitmapContainer中指存储了一个数据还是65536个数据,占用的空间都是同样的8kb。
③RunContainer
一种利用步长来压缩空间的方法。比如连续的整数序列11,12,13,14,15,27,28,29会被压缩为两个二元组11,4,27,2表示:11后面紧跟着4个连续递增的值,27后面跟着2个连续递增的值。这样一来,原先16个字节的空间,现在只需要8个字节。
问题分析
roaringbitmap扩展在不同数据库中的支持情况
数据库
支持roaringbimap扩展
KES
支持
pg
支持(开源插件)
oracle
不支持
mysql
不支持
dm8
不支持
roaringbitmap扩展介绍
功能
roaringbitmap通过逻辑复杂度来换空间时间复杂度的方法对存储性能进行优化。KES使用时需要注意:
1. 此扩展非内置扩展。
2. 可重定位:alter extension能把扩展换schema。
3. 支持在oracle、pg模式下创建此扩展,其他模式下不支持。
4. roaringbitmap支持create index语法。
使用
使用roaringbitmap扩展时,需要首先创建扩展:
支持创建扩展create extension roaringbitmap;
支持卸载扩展 drop extension roaringbitmap;
数据类型
类型名称
描述
roaringbitmap
本插件实现的基本类型,roaringbitmap类型。
使用示例:
select '{-1,3,5}'::roaringbitmap;
结果:
roaringbitmap
--------------------------------------------------------------------------------
\x3a3000000200000000000100ffff0000180000001c00000003000500ffff
(1 行记录)
函数
名称
描述
roaringbitmap_in
将字符串转换为roaringbitmap类型
roaringbitmap_out
将roaringbitmap类型转换为字符串
roaringbitmap_recv
将二进制转换为roaringbitmap类型
roaringbitmap_send
将roaringbitmap类型转换为二进制类型
roaringbitmap
将二进制形式转换为roaringbitmap类型
rb_and
将两个roaringbitmap类型进行与操作
rb_or
将两个roaringbitmap类型进行或操作
rb_xor
将两个roaringbitmap类型进行亦或操作
rb_andnot
将两个roaringbitmap类型进行not操作
rb_add
将roaringbitmap类型集合中添加int类型值
rb_remove
将roaringbitmap类型集合中移除int类型值
rb_shiftright
将roaringbitmap类型集合中的元素加上int类型值
rb_shiftleft
将roaringbitmap类型集合中的元素减去int类型值
rb_contains
判断两个roaringbitmap变量的包含关系
rb_containedby
判断两个roaringbitmap变量的包含关系
rb_intersect
返回两个roaringbitmap变量的交集
rb_equals
判断两个roaringbitmap变量是否相等
rb_not_equals
判断两个roaringbitmap变量是否不相等
rb_build
通过int数组构建roaringbitmap变量
rb_index
返回int类型值在roaringbitmap变量集合中的索引
rb_cardinality
返回roaringbitmap中的元素数量
rb_and_cardinality
返回两个集合交集的元素数量
rb_or_cardinality
返回两个集合并集的元素数量
rb_xor_cardinality
返回两个集合亦或操作后的元素数量
rb_andnot_cardinality
返回两个集合差集操作后的元素数量
rb_is_empty
判断roaringbitmap集合是否为空
rb_fill
对roaringbitmap进行填充
rb_remove
对roaringbitmap指定序列删除
rb_range
返回roaringbitmap中在值域范围内的集合
rb_range_cardinality
返回roaringbitmap中在值域范围内的元素数量
rb_min
返回roaringbitmap中的最小值
rb_max
返回roaringbitmap中的最大值
rb_rank
返回roaringbitmap中小于指定值的个数
rb_select
从roaringbitmap中返回指定数量的集合
rb_to_array
将roaringbitmap转换成int数组
rb_iterate
将roaringbitmap以表的形式输出
rb_or_agg
聚集函数,对roaringbitmap进行与操作
rb_or_cardinality_agg
聚集函数,对roaringbitmap进行与操作之后的元素个数
rb_and_agg
聚集函数,对roaringbitmap进行或操作
rb_and_cardinality_agg
聚集函数,对roaringbitmap进行或操作之后的元素个数
rb_xor_agg
聚集函数,对roaringbitmap进行亦或操作
rb_xor_cardinality_agg
聚集函数,对roaringbitmap进行亦或操作之后的元素个数
rb_gt
对两个roaringbitmap类型进行大于比较
rb_ge
对两个roaringbitmap类型进行大于等于比较
rb_lt
对两个roaringbitmap类型进行小于比较
rb_le
对两个roaringbitmap类型进行大于等于比较
rb_cmp
对两个roaringbitmap类型进行比较
使用示例1:
select rb_and_cardinality('{1,2,10}','{1,10,100}');
结果:
rb_and_cardinality
-------------------------
2
(1 行记录)
使用示例2:
select rb_index('{1,10,100}',99);
结果:
rb_index
---------------
-1
(1 行记录)
转换
源类型
目标类型
roaringbitmap
bytea
bytea
roaringbitmap
使用示例1:
select '{1,9999}'::roaringbitmap::bytea;
结果:
bytea
--------------------------------------------------------
\x3a30000001000000000001001000000001000f27
(1 行记录)
使用示例2:
select '{1}'::roaringbitmap::bytea::roaringbitmap;
结果:
roaringbitmap
-----------------------------------------------------
\x3a3000000100000000000000100000000100
(1 行记录)
操作符
左类型
操作符
右类型
roaringbitmap
&
roaringbitmap
roaringbitmap
|
roaringbitmap
roaringbitmap
|
int4
roaringbitmap
roaringbitmap
roaringbitmap
<<
bigint
roaringbitmap
>>
bigint
roaringbitmap
-
roaringbitmap
roaringbitmap
-
Int4
roaringbitmap
@>
roaringbitmap
roaringbitmap
@>
Int4
roaringbitmap
@<
roaringbitmap
Int4
@<
roaringbitmap
roaringbitmap
&&
roaringbitmap
roaringbitmap
=
roaringbitmap
roaringbitmap
<>
roaringbitmap
roaringbitmap
>
roaringbitmap
roaringbitmap
>=
roaringbitmap
roaringbitmap
<
roaringbitmap
roaringbitmap
<=
roaringbitmap
使用示例:
select roaringbitmap('{1,2,3}') @> roaringbitmap('{3,4,5}');
结果:
?column?
----------
f
(1 行记录)
索引
KES中的roaringbitmap插件支持Btree索引。
结论
KES支持roaringbitmap扩展,该扩展通过逻辑复杂度来换空间时间复杂度的方法对存储性能进行优化。