BitMap介绍
所以Bitmap本身会极大的节省储存空间。
如下图字符串在计算机里是由二进制的形式保存的。
我们可以在Redis中设置(SET)一个字符串,可以获取(GET),当然除了获取一个完整的字符串,在Redis中也可以对字符串二进制位进行操作。
Redis Getbit
返回值
字符串值指定偏移量上的位(bit)。
当偏移量 OFFSET 比字符串值的长度大,或者 key 不存在时,返回 0 。
下面一个案例
127.0.0.1:6379> set key1 big
OK
127.0.0.1:6379> getbit key1 0 #获取第一个字母的第一个偏移量
(integer) 0
127.0.0.1:6379> getbit key1 1 #获取第一个字母的第二个偏移量
(integer) 1
BitMap相关操作命令
1. getbit key offset : 对key所存储的字符串值,获取指定偏移量上的位(bit)。
2. setbit key offset value:对key所存储的字符串值,设置或清除指定偏移量上的位(bit):
1) 返回值为该位在setbit之前的值
2) value只能取0或1
3) offset从0开始,即使原位图只能10位,offset可以取1000
案例操作
127.0.0.1:6379> setbit key1 7 1 #将key1第一个字母的最后一个位设置为1
(integer) 0
127.0.0.1:6379> get key1
"cig"
3. bitcount key [start end]:获取位图指定范围中位值为1的个数如果不指定start与end则取所有。
使用bitcount命令查看二进制为1的个数就是13
127.0.0.1:6379> get key1
"cig"
127.0.0.1:6379> bitcount key1
(integer) 13
4. bitop op destKey key1 [key2...]:做多个BitMap的and(交集)、or(并集)、not(非)、xor(异或)操作并将结果保存在destKey中。
5. bitpos key tartgetBit [start end]:计算位图指定范围第一个偏移量对应的的值等于targetBit的位置:
1) 找不到返回-1。
2) start与end没有设置,则取全部。
3) targetBit只能取0或者1。
BitMap应用场景
1. 用户在线状态。
2. 用户签到。
3. 统计独立用户。
有1亿用户,5千万登陆用户,那么统计每日用户的登录数。每一位标识一个用户ID,当某个用户访问我们的网站就在Bitmap中把标识此用户的位设置为1。
这里做了一个使用set集合和BitMap存储的对比。
数据类型 | 每个 userid 占用空间 | 需要存储的用户量 | 全部占用内存量 |
set(集合) | 32位也就是4个字节(假设userid用的是整型,实际很多网站用的是长整型) | 50,000,000 | 32位 * 50,000,000 = 200 MB |
BitMap | 1 位(bit) | 100,000,000 | 1 位 * 100,000,000 = 12.5 MB |
时间在拉长一点
| 一天 | 一个月 | 一年 |
set(集合) | 200M | 6G | 72G |
BitMap | 12.5M | 375M | 4.5G |
计算后发现随着时间的增加,要记录数据量的增加,对比更加明显了,BitMap所占的空间比set(集合)更少。
在看另一个场景假如只有只有100万独立用户,在对比看看。
数据类型 | 每个 userid 占用空间 | 需要存储的用户量 | 全部占用内存量 |
set(集合) | 32位也就是4个字节(假设userid用的是整型,实际很多网站用的是长整型) | 1,000,000 | 32位 * 1,000,000 = 4 MB |
BitMap | 1 位(bit) | 100,000,000 | 1 位 * 100,000,000 = 12.5 MB |
发现BitMap也不是绝对的好,因为Bitmap本身要额外占用了空间。