-
Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具备很好的空间和时间效率,被用来检测一个元素是否是集合中的一个成员。
-
结 构
-
二进制
-
召回率
-
100%
-
方 法
-
哈希函数
Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具备很好的空间和时间效率,被用来检测一个元素是否是集合中的一个成员。若是检测结果为是,该元素不必定在集合中;但若是检测结果为否,该元素必定不在集合中。所以Bloom filter具备100%的召回率。这样每一个检测请求返回有“在集合内(可能错误)”和“不在集合内(绝对不在集合内)”两种状况,可见 Bloom filter 是牺牲了正确率和时间以节省空间。
如须要判断一个元素是否是在一个集合中,咱们一般作法是把全部元素保存下来,而后经过比较知道它是否是在集合内,链表、树都是基于这种思路,当集合内元素个数的变大,咱们须要的空间和时间都线性变大,检索速度也愈来愈慢。 Bloom filter 采用的是
哈希函数的方法,将一个元素映射到一个 m 长度的阵列上的一个点,当这个点是 1 时,那么这个元素在集合内,反之则不在集合内。这个方法的缺点就是当检测的元素不少的时候可能有冲突,解决方法就是使用 k 个哈希 函数对应 k 个点,若是全部点都是 1 的话,那么元素在集合内,若是有 0 的话,元素则不在集合内。
Bloom filter 优势就是它的插入和查询时间都是常数,另外它查询元素却不保存元素自己,具备良好的安全性。它的缺点也是显而易见的,当插入的元素越多,错判“在集合内”的几率就越大了,另外 Bloom filter 也不能删除一个元素,由于多个元素哈希的结果可能在 Bloom filter 结构中占用的是同一个位,若是删除了一个比特位,可能会影响多个元素的检测。
下面是一个简单的 Bloom filter 结构,开始时集合内没有元素
当来了一个元素 a,进行判断,这里哈希函数有两个,计算出对应的比特位上为 0 ,便是 a 不在集合内,将 a 添加进去:
以后的元素,要判断是否是在集合内,也是同 a 同样的方法,只有对元素哈希后对应位置上都是 1 才认为这个元素在集合内(虽然这样可能会误判):
随着元素的插入,Bloom filter 中修改的值变多,出现误判的概率也随之变大,当新来一个元素时,知足其在集合内的条件,即全部对应位都是 1 ,这样就可能有两种状况,一是这个元素就在集合内,没有发生误判;还有一种状况就是发生误判,出现了哈希碰撞,这个元素本不在集合内。