两个月之前——

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

要想统计所有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后' ;

两个月之后——

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

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

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

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

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

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

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

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

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

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

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

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

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

一周之后......

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

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

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

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

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

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

25769803776L  =  11000000000000000000000000000000000B

8589947086L = 1000000000000000000011000011001110B

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

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

3. 由于 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当中。

最终插入结果如下:

官方说明如下:

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

几点说明:

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

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

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

EWAHCompressedBitmap对应的maven依赖如下:
<dependency><groupId>com.googlecode.javaewah</groupId><artifactId>JavaEWAH</artifactId><version>1.1.0</version>
</dependency>

—————END—————

漫画:Bitmap算法相关推荐

  1. 【转】漫画:Bitmap算法

    漫画:Bitmap算法 转载于:https://www.cnblogs.com/apeway/p/10786283.html

  2. 漫画:Bitmap算法 整合版

    转载自  玻璃猫 程序员小灰 两个月之前-- 为满足用户标签的统计需求,小灰利用Mysql设计了如下的表结构,每一个维度的标签都对应着Mysql表的一列: 要想统计所有90后的程序员该怎么做呢? 用一 ...

  3. 漫画说算法--动态规划算法三(绝对通俗易懂,非常棒)

    在前两集漫画中,我们通过一个算法问题的完整解题过程,讲述了动态规划的基本概念和思想.没看过前两集的朋友可以点击下面的链接: 漫画说算法–动态规划算法一(绝对通俗易懂,非常棒) 漫画说算法–动态规划算法 ...

  4. 漫画说算法--动态规划算法二(绝对通俗易懂,非常棒)

    在上一篇漫画中,我们分析了一道动态规划相关的算法问题,并归纳出了问题的状态转移方程式.没看过上一篇的朋友可以点击下面的链接: 漫画说算法–动态规划算法一(绝对通俗易懂,非常棒) 首先,让我们简单回顾一 ...

  5. BitMap算法应用:Redis队列滤重优化

    工作中有用到Redis滤重队列. 原来的方法如下: 方法一 为了保证操作原子性,使用Redis执行Lua脚本. 在脚本中的逻辑是,如果队列不超过某个数值,进行一次lrem操作(队列使用list结构), ...

  6. 【算法与数据结构专场】BitMap算法基本操作代码实现

    上篇我们讲了BitMap是如何对数据进行存储的,没看过的可以看一下[算法与数据结构专场]BitMap算法介绍 这篇我们来讲一下BitMap这个数据结构的代码实现. 回顾下数据的存储原理 一个二进制位对 ...

  7. 《算法与数据结构专场》BitMap算法介绍

    我们先来看个简单的问题. 假如给你20亿个非负数的int型整数,然后再给你一个非负数的int型整数t,让你判断t是否存在于这20亿数种,你会怎么做呢? 有人可能会用一个int数组,然后把20亿个数给存 ...

  8. 漫画说算法--动态规划算法一(绝对通俗易懂,非常棒)

    题目: 有一座高度是10级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶.要求用程序来求出一共有多少种走法. 比如,每次走1级台阶,一共走10步,这是其中一种走法.我们可以简写成 1,1,1 ...

  9. 通过BitSet源码来理解BitMap算法

    BitMap是一种很常用的数据结构,它的思想的和原理是很多算法的基础,当然,并且在索引,数据压缩,海量数据处理等方面有广泛应用. 一.简介 BitMap 是一种很常用的数据结构,它的思想和原理是很多算 ...

  10. 生成模型--GAN用于图像漫画特效算法

    图像漫画特效算法   这种风格迁移的算法都快要被GAN统治了 . 主要思路   可以分两部分:   1)简化图像,即去除图像细节,仅保留图像主要信息:   在简化图像步骤,除了meanshift算法外 ...

最新文章

  1. Python代码转Latex公式,这个开源库用一行代码帮你搞定
  2. native 关键的理解
  3. Java 8流中的数据库CRUD操作
  4. UIView封装动画--iOS利用系统提供方法来做关键帧动画
  5. 根据/proc/meminfo对空闲内存进行占用
  6. 计算机二级分省和国家吗,计算机国家二级和省二级有什么区别?
  7. hbase 预写日志_HDInsight HBase 加速写入现已正式发布
  8. 删除链表倒数第N个节点
  9. Atitit 函数式常用子操作与组合 目录 1. 集合类的操作 1 1.1. Transform、map 1 1.2. paip.提升效率---filter map reduce 的java 函
  10. mysql导出数据库方法_mysql导出数据库几种方法
  11. [算法]在数组中找到一个局部最小的位置
  12. 数字电视输出标准规范和BT601/BT709/BT2020色域转换方法资料整理
  13. 批处理删除指定文件夹中的指定类型文件
  14. 盘点.确保物联网设备顺利运行的9项测试
  15. ipa文件生成扫码安装二维码的方法
  16. 怎么制作你的第一个机器人
  17. MC开服教程2:材质包法自定义唱片音乐
  18. java jar加密工具_Java加密流程-防止jar被反编译
  19. 介绍一些免费好用的静态网站托管服务
  20. 各平台电脑开启虚拟化的方法

热门文章

  1. Bridge(桥接)-对象结构型模式
  2. GameMap地图初始化
  3. HDU 2544 最短路 Dijkstra
  4. Hadoop 开源调度系统zeus
  5. 基于墨刀实现的原型系统:多啦阅读
  6. MYSQL 用户的操作
  7. MySQL内核月报 2014.11-MySQL· 5.7改进·Recovery改进
  8. Linux stat
  9. CentOs6.5配置安装DRBD
  10. 【sed 工具的使用】