【Bitmap算法浅谈篇】Mysql应用Bitmap

时间:2024-06-10 07:20:11

首先Bitmap算法并不是一种数学公式,而是一种方法!


下面通过一个列子来使你明白何为Bitmap算法!以下数据库以mysql为列!


给出一个表结构,每一行都表示一条记录!

【Bitmap算法浅谈篇】Mysql应用Bitmap


1、要想统计所有70后的演员怎么做?

Select count(distinct Name) as 用户数 from table where Age='70后' and Job='演员';


2、要想统计所有Apple手机使用者或者80后的用户总和怎么做?

Select count(distinct Name) as 用户数 from table where Phone='Apple' or Age='80后';


是不是很简单,几个月后你的数据库越来越长,后面的标签越来越多,导致你sql语句拼接出来是如此的长,而且多个用户求并集的时候用distinct,性能慢的会让人崩溃!


这个时候Bitmap思想就出来了,如果我们可以把一个数据映射到内存的一个bit上,这样对于通过位操作就可以快速的实现大型数据的去重和查询。


举个列子,给出一长度为10bit的内存空间,想要插入整型数据4,3,2,1。


第一步:10bit的所有位数据均为0。


【Bitmap算法浅谈篇】Mysql应用Bitmap


第二步:把数据4存入bitmap,映射到内存存储的位置就是下标为4的位置,将此位置为1。


【Bitmap算法浅谈篇】Mysql应用Bitmap


第三步:把数据3存入bitmap,映射到内存存储的位置就是下标为3的位置,将此位置为1。


【Bitmap算法浅谈篇】Mysql应用Bitmap


第四步:把数据2存入bitmap,映射到内存存储的位置就是下标为2的位置,将此位置为1。


【Bitmap算法浅谈篇】Mysql应用Bitmap


第五步:把数据1存入bitmap,映射到内存存储的位置就是下标为1的位置,将此位置为1。


【Bitmap算法浅谈篇】Mysql应用Bitmap


现在问此时bitmap里存了什么哪些数据?显然4,3,2,1。


那到底跟我上面数据库查询有什么关系?我们来想想,我们的用户标签能不能用Bitmap的形式来存储?

出现上面mysql的查询复杂是因为我们一个用户对应多个标签,如果我们让一个标签对应多个用户呢?这个时候我们就要建立用户名和用户ID的映射,然后让每一个标签存储包含此标签的的用户ID!


比如:

1、建立用户名和用户的ID的映射


【Bitmap算法浅谈篇】Mysql应用Bitmap

【Bitmap算法浅谈篇】Mysql应用Bitmap


2、让每个标签存储包含此标签的所有用户ID,每个标签都是独立的bitmap。


【Bitmap算法浅谈篇】Mysql应用Bitmap


3、这样,实现用户的去重和查询统计,就变的简单了!


【Bitmap算法浅谈篇】Mysql应用Bitmap



【Bitmap算法浅谈篇】Mysql应用Bitmap


好了这就是bitmap的应用!


有人或许不明白HashSet和HashMap也能同样实现去重和统计,我们要用Bitmap,其实他们的每一个ID都存储成int型,占内存多啊,bit只占1,32倍的空间节省!而且bitmap在用户做交集和并集运算很方便,就是平时我们常用的位运算。


1、如何查找使用Apple手机的演员用户?


【Bitmap算法浅谈篇】Mysql应用Bitmap


【Bitmap算法浅谈篇】Mysql应用Bitmap


使用Apple手机的演员用户(0000001010B & 0000000010B =0000000010B)


【Bitmap算法浅谈篇】Mysql应用Bitmap



2、如何查找所有男性或者80后的用户?


【Bitmap算法浅谈篇】Mysql应用Bitmap


【Bitmap算法浅谈篇】Mysql应用Bitmap


男性或者80后的用户(0000001100B | 0000000110B =0000001110B)


【Bitmap算法浅谈篇】Mysql应用Bitmap


当然bitmap也会有缺点,那就是在不知道总用户的情况下,无法用非运算!

最后给个开源的bitmap,谷歌开发的EWAHCompressedBitmap!这个我下篇文章会分析它的存储结构!