Bitmap数据结构的原理与使用

参考:

https://www.cnblogs.com/LBSer/p/3322630.html

https://www.cnblogs.com/yangjiannr/p/da-shu-ju-chu-libitmap.html

最近在研究各种OLAP引擎的时候,发现很多地方都有使用Bitmap,特别是大数据领域,Bitmap有很多应用场景,而自身之前对这块只是稍有了解,并为做太多深入,因此进行整理分享。

1.Bitmap的概念

1.1 Bitmap的基本概念

在这里插入图片描述

当数据量很大而每个数据的状态又很少的情况时候,可以用位图来设计存储数据的容器。

1.2 Bitmap的基本思想

将一个数据状态较少的变量,转换为一个状态位bit(只有0和1两种状态),存储到一个顺序的bit数组中,从而在海量数据中快速定位所需数据状态的数据。这种做法不仅节省内存空间,而且能够快速定位数据位置,在海量数据的排序、查询、去重相关处理中有极高的效率。

1.3 Bitmap的案例

有1亿条用户数据,用户数据中有性别字段sex(0-男,1-女),如果使用int加载到内存,需要使用 32Bit * 1亿 = 400MB ,那么如果将用户的性别数据转换为Bitmap存储就变成 1Bit * 1亿 = 12.5M ,存储降低了32倍 ,构建2个1亿bit的数组,sex枚举值【男】对应一个bit数组,枚举值【女】对应一个bit数组,将1亿个用户的性别数据依次按顺序存放状态(是存1,否存0),得到bitmap数组序列位: 1000101001 。。。。,对【女】的bit数组同样操作,就得到两个key【男】和【女】分别对应的bitmap,这样要筛选对应key时,直接读取key的bitmap中状态位为1的位置,而不用读取数据本身,就可以快速定位到数据

2.Bitmap的常用场景

2.1 Bitmap应用之快速排序

场景:我们需要对6个10以内不重复数(2,5,4,7,1,8)进行快速排序。

方法:创建一个10bit的bitmap数组,其初始状态为:0 0 0 0 0 0 0 0 0 0 ,然后依次读取6个数,从左至根据其数值大小在bit数组对应位置上置1(顺序从左至右0位算起),比如读取2更改状态位之后,bitmap数组为: 0 0 1 0 0 0 0 0 0 ;接着读取 5更改状态位之后,bitmap数组为: 0 0 1 0 0 1 0 0 0 0 , 读完所有值更新状态位之后bitmap变成: 0 1 1 0 1 1 0 1 1 0 。最后将bitmap中状态为1 的位置依次输出得到序列:1 2 4 5 7 8

优点:运算效率高,不需要进行比较和移位;占内存小;复杂度位O(n)

缺点:所有的数据不能重复。即不可对重复的数据进行排序和查找。

2.2 Bitmap应用之快速去重

场景:有2.5亿个Int整形数字,需要统计不重复的数字个数,但是内存无法存下2.5亿个数字。

方法:使用bitmap,2个bit位存储同一个数值的状态(00—不存在,01–出现1次,10—出现两次及以上,11—不处理状体),然后构建一个bitmap数组,分别依次读取数字,根据数组进行偏移设置状态(每次偏移量位2的倍数),最终统计bitmap中状态位为 01 的个数,即可

优点:内存占用小,复杂度O(n)

2.3 Bitmap应用之快速查询

场景:一个1亿条以上数据的集合,筛选出字段status某种状态值的数据

方法:对字段status的每种状态构建bitmap,依次读取记录在对应状态位上设置状态(0-不存在,1-存在)。这样在获取某种状态的数据时,直接读取这种status值的bitmap从而快速筛选出对应记录。

优点:查询快速,内存运算,不用读取原始数据,复杂度O(n)

缺点:数据记录本身需要有顺序,不可重复

2.Bitmap索引

2.1 Bitmap索引原理

Bitmap索引就是使用Bitmap来定位数据的一种倒排索引(索引排列由低位到高位),能够快速定位数据,提高数据记录查询效率。

2.2 Bitmap索引举例

比如,如下表:

create table test_user(
id int primary key,
name varchar(100) comment '姓名',
sex tinyint comment '性别:0-男,1-女'
age tinyint comment '年龄',
married tinyint comment '婚姻状态:0-未婚、1-已婚、2-离婚'
)
;
对应数据如下:
1,jack,11,0
2,lily,30,1
3,tom,23,1
4,tony,55,2
5,jerry,35,0

当我们对married字段建立Bitmap Index时,索引底层就会对married的所有值构建一个字典,

字典ID字典值备注
10未婚
21已婚
32离婚

然后对字典中每一个值构建一个Bitmap,最终的形式如下:

字典ID对应Bitmap倒排索引备注
110001第1、5行是该值
200110第2、3行是该值
301000第4行是该值

那么在通过where married=1时,就会先找到married=1对应的字典ID为2,然后再找到字典ID为2的Bitmap,从而筛选出第2、3行数据。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值