mysql bitmap实现_bitmap原理和应用

bitmap数据结构

32位机器上的自然数一共有2的32次方约42亿个,如果用一个bit来存放一个整数,1代表存在,0代表不存在,那么把全部自然数存储在内存只要4294967296 / (8 * 1024 * 1024) = 512MB(8bit = 一个字节),而这些自然数存放在文件中,一行一个数字,1个整数4个字节,4*8*512MB需要16G的容量。可见,bitmap算法节约了非常多的空间。

970c367460b1

ps:占内存 10bit

应用:

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

使用场景:

开发一个用户画像系统,实现用户信息的标签化。用户标签包含用户的社会属性,生活习惯,消费行为。

通过用户标签,实现多样的用户群体统计,统计用户的男女比例,统计喜欢旅游的用户数量等。

1. 建立用户名和用户ID的映射:  1->me   2->you  3->he

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

男[1,2]   女[3] 爱旅游[2]  程序员[1,2]

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

970c367460b1

Bitmap在做交集和并集运算的时候也有极大的便利。位运算的高性能。

男性的程序员  110&110=110

不能做非运算,并不是除了1,2的其他都是女性,其实只有3是女性。除非提供一个全量的Bitmap,做异或即可。

970c367460b1

一个很长的Bitmap里使用率低的话很浪费空间。

谷歌所实现的EWAHCompressedBitmap中,对存储空间做了优化:

com.googlecode.javaewah

JavaEWAH

1.1.0

redis 用setbit(bitmap)统计活跃用户

Redis支持对String类型的value进行基于二进制位的置位操作。通过将一个用户的id对应value上的一位,通过对活跃用户对应的位进行置位,就能够用一个value记录所有活跃用户的信息。如下图所未,下图中的bitmap有9个位被置为1,表示这9个位上对应的用户是今天的活跃用户。其中第15位表示uid为15的用户,第一位表示uid为0的用户。(如果你的uid不是从1开始的,比如从100000开始,实际上你也可以相应的用uid减去初始值来表示其位数,比如1000000用户对应到bitmap的第一位)

970c367460b1

具体的代码类似下面这样:

redis.setbit(play:yyyy-mm-dd, user_id, 1)

这样一次记录的复杂度是O(1),在Redis中速度非常快。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值