漫画:Bitmap算法

冷不防 2023-07-12 09:29 237阅读 0赞

format_png

format_png 1

format_png 2

format_png 3

两个月之前——

format_png 4

format_png 5

format_png 6

format_png 7

format_png 8

为满足用户标签的统计需求,小灰利用Mysql设计了如下的表结构,每一个维度的标签都对应着Mysql表的一列:

format_png 9

要想统计所有90后的程序员该怎么做呢?

用一条求交集的SQL语句即可:

Select count(distinct Name) as 用户数 from table whare age = ‘90后’ and Occupation = ‘程序员’ ;

要想统计所有使用苹果手机或者00后的用户总合该怎么做?

用一条求并集的SQL语句即可:

Select count(distinct Name) as 用户数 from table whare Phone = ‘苹果’ or age = ‘00后’ ;

format_png 10

两个月之后——

format_png 11

format_png 12

format_png 13

format_png 14

———————————————

format_png 15

format_png 16

format_png 17

format_png 18

format_png 19

  1. 给定长度是10的bitmap,每一个bit位分别对应着从0到9的10个整型数。此时bitmap的所有位都是0。

    format_png 20

  1. 把整型数4存入bitmap,对应存储的位置就是下标为4的位置,将此bit置为1。

format_png 21

  1. 把整型数2存入bitmap,对应存储的位置就是下标为2的位置,将此bit置为1。

format_png 22

  1. 把整型数1存入bitmap,对应存储的位置就是下标为1的位置,将此bit置为1。

format_png 23

  1. 把整型数3存入bitmap,对应存储的位置就是下标为3的位置,将此bit置为1。

format_png 24

要问此时bitmap里存储了哪些元素?显然是4,3,2,1,一目了然。

Bitmap不仅方便查询,还可以去除掉重复的整型数。

format_png 25

format_png 26

format_png 27

format_png 28

format_png 29

format_png 30

  1. 建立用户名和用户ID的映射:

format_png 31

  1. 让每一个标签存储包含此标签的所有用户ID,每一个标签都是一个独立的Bitmap。

format_png 32

  1. 这样,实现用户的去重和查询统计,就变得一目了然:

format_png 33

format_png 34

format_png 35

format_png 36

format_png 37

  1. 如何查找使用苹果手机的程序员用户?

format_png 38

  1. 如何查找所有男性或者00后的用户?

format_png 39

format_png 40

format_png 41

format_png 42

format_png 43

format_png 44

format_png 45

format_png 46

format_png 47

一周之后……

format_png 48

format_png 49

format_png 50

format_png 51

我们以上一期的用户数据为例,用户基本信息如下。按照年龄标签,可以划分成90后、00后两个Bitmap:

format_png 52

用更加形象的表示,90后用户的Bitmap如下:

format_png 53

这时候可以直接求得90后的用户吗?直接进行非运算?

format_png 54

显然,非90后用户实际上只有1个,而不是图中得到的8个结果,所以不能直接进行非运算。

format_png 55

format_png 56

同样是刚才的例子,我们给定90后用户的Bitmap,再给定一个全量用户的Bitmap。最终要求出的是存在于全量用户,但又不存在于90后用户的部分。

format_png 57

如何求出呢?我们可以使用异或操作,即相同位为0,不同位为1。

format_png 58

format_png 59

format_png 60

format_png 61

format_png 62

format_png 63

format_png 64

format_png 65

format_png 66

format_png 67

format_png 68

format_png 69

format_png 70

format_png 71

format_png 72

format_png 73

format_png 74

format_png 75

format_png 76

format_png 77

format_png 78

format_png 79

format_png 80

format_png 81

format_png 82

format_png 83

format_png 84

format_png 85

format_png 86

format_png 87

format_png 88

format_png 89

format_png 90

format_png 91

25769803776L = 11000000000000000000000000000000000B

8589947086L = 1000000000000000000011000011001110B

format_png 92

format_png 93

format_png 94

format_png 95

format_png 96

format_png 97

1.解析Word0,得知当前RLW横跨的空Word数量为0,后面有连续3个普通Word。

2.计算出当前RLW后方连续普通Word的最大ID是 64 X (0 + 3) -1 = 191。

  1. 由于 191 < 400003,所以新ID必然在下一个RLW(Word4)之后。

4.解析Word4,得知当前RLW横跨的空Word数量为6247,后面有连续1个普通Word。

5.计算出当前RLW(Word4)后方连续普通Word的最大ID是191 + (6247 + 1)X64 = 400063。

6.由于400003 < 400063,因此新ID 400003的正确位置就在当前RLW(Word4)的后方普通Word,也就是Word5当中。

最终插入结果如下:

format_png 98

format_png 99

format_png 100

format_png 101

format_png 102

官方说明如下:

  1. * Though you can set the bits in any order (e.g., set(100), set(10), set(1),
  2. * you will typically get better performance if you set the bits in increasing order (e.g., set(1), set(10), set(100)).
  3. *
  4. * Setting a bit that is larger than any of the current set bit
  5. * is a constant time operation. Setting a bit that is smaller than an
  6. * already set bit can require time proportional to the compressed
  7. * size of the bitmap, as the bitmap may need to be rewritten.

format_png 103

几点说明:

  1. 该项目最初的技术选型并非Mysql,而是内存数据库hana。本文为了便于理解,把最初的存储方案写成了Mysq数据库。

1.文中介绍的Bitmap优化方法在一定程度上做了简化,源码中的逻辑要复杂得多。比如对于插入数据400003的定位,和实际步骤是有出入的。

2.如果同学们有兴趣,可以亲自去阅读源码,甚至是尝试实现自己的Bitmap算法。虽然要花不少时间,但这确实是一种很好的学习方法。

  1. EWAHCompressedBitmap对应的maven依赖如下:
  2. <dependency>
  3. <groupId>com.googlecode.javaewah</groupId>
  4. <artifactId>JavaEWAH</artifactId>
  5. <version>1.1.0</version>
  6. </dependency>

—————END—————

发表评论

表情:
评论列表 (有 0 条评论,237人围观)

还没有评论,来说两句吧...

相关阅读

    相关 数据算法: Bitmap

    1. 初识 Bitmap Bitmap 也被称为位图。Bitmap 既是一种数据结构,又是一种图片类型。从数据结构的角度讲,Bitmap 适用于以下场景,后文会逐一进行阐

    相关 bitmap 位图算法

    由来,方便处理大数据的问题 比如,给你40亿个数,判断其中一个数是否存在 桶排序,或者哈希表的形式,消耗的内存太大,以及时间也会增加。 又或者是处理,40亿个数的排序

    相关 Bitmap算法简介

    Bitmap算法中文又叫做位图算法。那么什么是Bitmap算法呢? 位图算法中的位图是内存中连续的二进制位(bit),用于对大量整形数据做去重和查询。 举个例子,给定一块长

    相关 BitMap算法详解

    [BitMap算法详解][BitMap]   所谓的BitMap就是用一个bit位来标记某个元素所对应的value,而key即是该元素,由于BitMap使用了bit位来存

    相关 算法——001BitMap(位图)算法

    哈希表在查找定位操作上具有O(1)的常量时间,常用于做性能优化,但是内存毕竟是有限的,当数据量太大时用哈希表就会内存溢出了。而考虑对这些大数据进行存盘分批处理又有IO上的开销,