什么是布隆过滤器
布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于快速检查一个元素是否存在于一个集合中。
布隆过滤器由一个长度为 m 的位数组和 k 个哈希函数组成。
- 开始时,布隆过滤器的每个位都被设置为 0。
- 当一个元素被添加到过滤器中时,它会被 k 个哈希函数分别计算得到 k 个位置,然后将位数组中对应的位设置为 1。
- 当检查一个元素是否存在于过滤器中时,同样使用 k 个哈希函数计算位置,如果任一位置的位为 0,则该元素肯定不在过滤器中;如果所有位置的位都为 1,则该元素可能在过滤器中。
布隆过滤器存在误判
布隆过滤器的优点是空间效率和查询时间都远远超过一般的算法,缺点是存在误判和删除困难。 当布隆过滤器保存的元素越多,被置为 1 的 bit 位就会越多。假设元素 x 没有存储过,但其他元素的哈希函数映射到位数组的三个位刚好都为 1 且恰好覆盖了元素 x 映射的位置,那么对于布隆过滤器来讲,元素 x 这个值就是存在的,也就是说布隆过滤器存在一定的误判率。
布隆过滤器的误判率取决于以下几个因素:
- 位数组的大小(m):位数组的大小决定了可以存储的标志位数量。如果位数组过小,那么哈希碰撞的几率就会增加,从而导致更高的误判率。
- 哈希函数的数量(k):哈希函数的数量决定了每个元素在位数组中标记的位数。哈希函数越多,碰撞的概率也会相应变化。如果哈希函数太少,则过滤器很快会变得不精确;如果太多,误判率也会升高,效率下降。
- 存入的元素数量(n):存入的元素越多,哈希碰撞的几率越大,从而导致更高的误判率。
误判率公式如下:
虽然布隆过滤器会产生误判,但在很多场景下一定的误判率是可以接受的,这是因为布隆过滤器的主要优点是其高效的查询速度和低内存占用。相比其他精确的集合数据结构(如哈希表、树等),布隆过滤器可以在空间效率和查询速度上表现更优。 布隆过滤器其实并不支持删除元素,因为多个元素可能哈希到一个布隆过滤器的同一个位置,如果直接删除该位置的元素,则会影响其他元素的判断。
布隆过滤器支持删除吗
布隆过滤器其实并不支持删除元素,因为多个元素可能哈希到一个布隆过滤器的同一个位置,如果直接删除该位置的元素,则会影响其他元素的判断。
为什么不能用哈希表而是用布隆过滤器
布隆过滤器是一种基于位数组和多个哈希函数的概率型数据结构,适合在内存资源有限、数据量大且能容忍一定误判的场景下使用。
相比哈希表,布隆过滤器的内存开销非常小,能快速判断一个元素是否存在。虽然它存在误判,但不会漏报,因此在防止缓存穿透、黑名单过滤和推荐系统去重等场景中广泛使用。
哈希表虽然可以精准判断元素存在与否,但需要存储实际数据,内存开销大,不适合大规模数据存储。
布隆过滤器的优点
- 内存效率高:布隆过滤器只需要存储每个元素的哈希值,而不需要存储元素本身,因此内存占用非常小。
- 查询速度快:布隆过滤器只需要将元素通过多个哈希函数映射到位数组,并检查位状态即可。它不需要哈希表那样的复杂键值操作,时间复杂度接近常数时间,速度非常快。