bitmap算法和布隆过滤器都是用来当数据量很大时用于信息的记录和去重的,但它们有相同的地方也有不同的地方,下面就先来介绍下bitmap算法:
bitmap算法的思路是利用一个bit位图去记录信息是否存在,举个例子,假设你有一个数组[2,4,7,9],你如果用int型数组去记录它,那么它就需要4*4=16个字节,4*4*8=128个bit,但用bitmap算法存储就能节省很多空间,下面以[2,4,7,9]为例描述bitmap算法:
首先,取出这个数组(这里记为arr)里的最大值max = 9.
然后申请一个bool型数组bitmap,长度 = max+1 = 10.
然后遍历数组,令bitmap[arr[i]] = true.
算法很简单,我们来看看算法完成后效果是怎么样的,算法完成后我们得到了一个bitmap[9]的bool型数组,值为[0,0,1,0,1,0,0,0,1,0,1](这里1表示true,0表示false),只要bitmap数组相应位置为1,则表示原数组有这个数,我们来看看占用的空间,只需要10*1=10个bit,大大的节省了空间。我们再来看一个实际用例,加深下理解。
假设有一个表项如下
用一条求交集的SQL语句统计90后数量:
Select count(distinct Name) as 用户数 from table whare age = '90后' and Occupation = '程序员' ;
用ID作为bitmap的序列。
90后的bitmap
到这里,bitmap的概念就说的差不多了,下面再说下布隆过滤器(bloom filter):
说到布隆过滤器,就不得不提到hash表,当数据量不太大时,用hash表存储就可以轻松的判断一个数据是否存在,但当数据量很大时,为了让hash表不冲突,hash表所占用的空间就需要非常大了,这个时候就引入了bloom filter,bloom filter的底层就是bitmap,中间的算法转换就是hash函数,bloom filter的思想如下
准备k个hash函数,准备一个长度为m的bitmap空间,对于每个数据:
每经过一个hash函数得到一个Index。
将bitmap[index]置为1。
这样相对与直接用hash表会节省很多空间,但bloom filter有一些问题,主要就是它可能存在误判,误算率是其中之一。随着存入的元素数量增加,误算率随之增加。但是如果元素数量太少,则使用散列表足矣。(误判补救方法是:再建立一个小的白名单,存储那些可能被误判的信息。) 另外,一般情况下不能从布隆过滤器中删除元素。我们很容易想到把位数组变成整数数组,每插入一个元素相应的计数器加 1, 这样删除元素时将计数器减掉就可以了。然而要保证安全地删除元素并非如此简单。首先我们必须保证删除的元素在布隆过滤器里面. 这一点单凭这个过滤器是无法保证的。另外计数器回绕也会造成问题。
下面再推导一下bloom filter的误判概率
