Bitmaps这个数据结构可以实现对位的操作。Bitmaps实际上就是字符串,但是它可以对字符串的位进行操作。
可以把Bitmaps想象成一个以位为单位数组,数组中的每个单元只能存0或者1,数组的下标在bitmaps中叫做偏移量。单个bitmaps的最大长度是512MB,即2^32个比特位。
详细可以参考大佬写的
getbit key offset
setbit key offset value
使用bitmap来记录 周一到周日的打卡! 周一:1 周二:0 周三:0 周四:1..... 127.0.0.1:6379> setbit sign 0 1 (integer) 0 127.0.0.1:6379> setbit sign 1 0 (integer) 0 127.0.0.1:6379> setbit sign 2 0 (integer) 0 127.0.0.1:6379> setbit sign 3 1 (integer) 0 127.0.0.1:6379> setbit sign 4 1 (integer) 0 127.0.0.1:6379> setbit sign 5 0 (integer) 0 127.0.0.1:6379> setbit sign 6 0 (integer) 0 # 查看某一天是否有打卡! 127.0.0.1:6379> getbit sign 3 (integer) 1 127.0.0.1:6379> getbit sign 6 (integer) 0 #统计操作,统计打卡的天数 127.0.0.1:6379> bitcount sign # 统计这周打卡记录,就可以看见是否全勤 (integer) 3
解决方案
对指定key按位进行交、并、非、异或操作,并将结果保存到destKey中
bitop op destKey key1 [key2…]
统计指定key中1的数量
bitcount key [start end]
状态的统计 127.0.0.1:6379> setbit 20201229 0 1 # 20201229日这一天 0号电脑 点播过 因此为1 (integer) 0 127.0.0.1:6379> setbit 20201229 4 1 (integer) 0 127.0.0.1:6379> setbit 20201229 8 1 (integer) 0 127.0.0.1:6379> setbit 20201230 0 1 (integer) 0 127.0.0.1:6379> setbit 20201230 5 1 (integer) 0 127.0.0.1:6379> setbit 20201230 8 1 (integer) 0 127.0.0.1:6379> bitcount 20201229 (integer) 3 127.0.0.1:6379> bitcount 20201230 (integer) 3 127.0.0.1:6379> setbit 20201229 6 1 (integer) 0 127.0.0.1:6379> bitcount 20201229 (integer) 4 127.0.0.1:6379> bitop or 29-30 20201229 20201230 # 合并 (integer) 2 127.0.0.1:6379> bitcount 29-30 # 就可以查看出有多少电影被点播 (integer) 5
Redis 2.8.9版本就更新了Hyperloglog数据结构
Redis Hyperloglog 基数统计的算法
优点:占用的内存是固定,2^64 不同的元素的基数,只需要费12kb内存 。如果要从内存角度来比较的话 Hyperloglog 就是首选
网页的UV(一个人访问一个网站多次,但是还是算作一个人)
传统的方式,set保存用户的id,然后就可以统计set中元素数量作为标准判断!这个方式如果保存大量的用户id,就会比较麻烦,我们的目的是为了计数,而不是保存用户id
基数
添加数据
pfadd key element [element …]
统计数据
pfcount key [key …]
合并数据
pfmerge destkey sourcekey [sourcekey…]
127.0.0.1:6379> pfadd mykey a b c d e f g h i j # 创建第一组元素 mykey (integer) 1 127.0.0.1:6379> pfcount mykey # 统计mykey中元素的基数数量 (integer) 10 127.0.0.1:6379> pfadd mykey2 i j z x c v b n a m # 创建第二组元素 mykey2 (integer) 1 127.0.0.1:6379> pfcount mykey2 (integer) 10 127.0.0.1:6379> pfmerge mykey3 mykey mykey2 # 合并两组 mykey mykey2 => mykey3 并集 OK 127.0.0.1:6379> pfcount mykey3 # 查看并集的数量! (integer) 15
如果允许容错,那么一定可以使用Hyperloglog!
如果不允许容错 ,就使用set或者自己的数据类型即可!
相关说明
Geospatial 地理位置
朋友的定位,附近的人,打车距离计算,但是计算出来的位置只算水平距离,不算垂直距离
Redis的Geo在Redis3.2版本就推出了!这功能可以推算地理位置的信息,两地之间的距离,方圆几里的人
添加坐标点
geoadd key longitude latitude member [longitude latitude member …]
获取坐标点
geopos key member [member …]
计算坐标点距离
geodist key member1 member2 [unit]
根据坐标点求范围内的数据
georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count]
根据点求范围内数据
georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count]
获取指定点对应的坐标hash值
geohash key member [member …]
geoadd 添加地理位置 规则:两极无法直接添加,我们一般会下载城市数据,直接通过java程序一次性导入! 参数 key 值(经度,纬度,名称) 有效的经度从-180度到180度 有效的维度从-85.05112878度到85.05112878度 127.0.0.1:6379> geoadd china:city 116.40 39.90 beijing (integer) 1 127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai (integer) 1 127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqin (integer) 1 127.0.0.1:6379> geoadd china:city 120.16 30.24 hangzhou 114.05 22.52 shengzhen 108.96 34.26 xian (integer) 3 geopos 获得当前定位:一定是一个坐标值 获取指定城市的经度和纬度 127.0.0.1:6379> geopos china:city beijing chongqin xian shengzhen 1) 1) "116.39999896287918091" 2) "39.90000009167092543" 2) 1) "106.49999767541885376" 2) "29.52999957900659211" 3) 1) "108.96000176668167114" 2) "34.25999964418929977" 4) 1) "114.04999762773513794" 2) "22.5200000879503861" geodist 两人之间的距离 单位: m 表示单位为米。 km 表示单位为千米。 mi 表示单位为英里。 ft 表示单位为英尺。 127.0.0.1:6379> geodist china:city beijing shanghai # 查看北京到上海的直线距离 "1067378.7564" 127.0.0.1:6379> geodist china:city beijing shanghai km "1067.3788" 127.0.0.1:6379> geodist china:city beijing chongqin km "1464.0708" 127.0.0.1:6379> geodist china:city beijing xian km "910.0565" georadius 以给定的经纬度为中心, 找出某一半径内的元素 我附近的人(获取所有附近的人的地址 定位)通过半径来查询 所有的数据都应该录入:china:city 才会让结果更加清晰 127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km # 以110 30这个经纬度为中心寻找方圆1000km内的城市 1) "chongqin" 2) "xian" 3) "shengzhen" 4) "hangzhou" 127.0.0.1:6379> GEORADIUS china:city 110 30 500 km 1) "chongqin" 2) "xian" 127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withcoord # 显示他人的定位信息 1) 1) "chongqin" 2) 1) "106.49999767541885376" 2) "29.52999957900659211" 2) 1) "xian" 2) 1) "108.96000176668167114" 2) "34.25999964418929977" 127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist # 显示到中心距离的位置 1) 1) "chongqin" 2) "341.9374" 2) 1) "xian" 2) "483.8340" # 筛选出指定的的结果 127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist withcoord count 1 1) 1) "chongqin" 2) "341.9374" 3) 1) "106.49999767541885376" 2) "29.52999957900659211" 127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist withcoord count 2 1) 1) "chongqin" 2) "341.9374" 3) 1) "106.49999767541885376" 2) "29.52999957900659211" 2) 1) "xian" 2) "483.8340" 3) 1) "108.96000176668167114" 2) "34.25999964418929977" 127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist withcoord count 3 1) 1) "chongqin" 2) "341.9374" 3) 1) "106.49999767541885376" 2) "29.52999957900659211" 2) 1) "xian" 2) "483.8340" 3) 1) "108.96000176668167114" 2) "34.25999964418929977" GEORADIUSBYMEMBER 找出位于指定元素周围的其他元素 127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1000 km 1) "beijing" 2) "xian" 127.0.0.1:6379> GEORADIUSBYMEMBER china:city shanghai 200 km 1) "hangzhou" 2) "shanghai" GEOHASH 返回一个或多个位置元素的 Geohash 将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么则距离越近 127.0.0.1:6379> geohash china:city beijing chongqin 1) "wx4fbxxfke0" 2) "wm5xzrybty0" GEO底层的实现原理其实就是Zset 我们可以使用Zset命令来操作geo zrem移除 127.0.0.1:6379> zrange china:city 0 -1 # 查看地图中全部的元素 1) "chongqin" 2) "xian" 3) "shengzhen" 4) "hangzhou" 5) "shanghai" 6) "beijing" 127.0.0.1:6379> zrem china:city beijing # 移除指定的元素 (integer) 1