bitmap
官方说明
bitmap 事实上不是数据类型,而是一组 定义在 string 类型上、面向二进制位** **的操作。string 数据类型是二进制安全的,并且它最大可存储 512MB 的值,因此 bitmap 可以存储 2^32 个不同的二进制位
bitmap 最大的优势之一是存储信息时,它经常可以极大的节省空间。例如,一个用户的系统中,使用递增的 id 来表示不同的用户,这时候 bitmap 使用 512MB 内存就可以记录 40 亿用户的一个比特信息(例如,1是男生,0是女生,一个男生的id为19,那么这个 bitmap 的第 19 位就是 1)。
通常 bitmap 的使用例子是:
- 各种实时分析
- 存储于对象 id 相关联的、节省空间的、高性能的布尔信息
setbit
向 key 中设置一个 bit
127.0.0.1:6379> setbit mybit 0 1
(integer) 0
127.0.0.1:6379> setbit mybit 10 1
(integer) 0
127.0.0.1:6379> setbit mybit 15 0
(integer) 0
复制代码
第一个参数是 key 的名称,第二个是 bit 在第几位,第三个是 bit 的值(0或1)
getbit
获取 bitmap 中指定位置的 bit 值,没有设置过值的位默认为0
127.0.0.1:6379> setbit mybit 0 1
(integer) 0
127.0.0.1:6379> setbit mybit 10 1
(integer) 0
127.0.0.1:6379> setbit mybit 15 0
(integer) 0
127.0.0.1:6379> getbit mybit 0
(integer) 1
127.0.0.1:6379> getbit mybit 10
(integer) 1
127.0.0.1:6379> getbit mybit 15
(integer) 0
127.0.0.1:6379> getbit mybit 16 # 没有设置过值的位默认为0
(integer) 0
复制代码
bitcount
计算 bitmap 中存储的 1 的个数
127.0.0.1:6379> setbit mybit 0 1
(integer) 0
127.0.0.1:6379> setbit mybit 10 1
(integer) 0
127.0.0.1:6379> setbit mybit 15 0
(integer) 0
127.0.0.1:6379> bitcount mybit
(integer) 2
复制代码
bitpos
找出 bitmap 中指定范围内第一个 0 或 1 的位置
127.0.0.1:6379> setbit mybit 3 0
(integer) 0
127.0.0.1:6379> setbit mybit 5 1
(integer) 0
127.0.0.1:6379> setbit mybit 7 1
(integer) 0
127.0.0.1:6379> bitpos mybit 1 0 -1 # 最后两个参数设置检索范围, 0 -1 表示所有的数
(integer) 5
127.0.0.1:6379> bitpos mybit 0 0 -1
(integer) 0
复制代码
bitop
对多个 bitmap 进行 and(与)、or(或)、xor(异或)操作,还有针对一个 bitmap 的 not(非) 这里只对 or 操作进行演示
127.0.0.1:6379> setbit mybit1 0 1
(integer) 0
127.0.0.1:6379> setbit mybit1 1 0
(integer) 0
127.0.0.1:6379> setbit mybit2 0 0
(integer) 0
127.0.0.1:6379> setbit mybit2 1 1
(integer) 0
127.0.0.1:6379> bitop or mybit3 mybit1 mybit2
(integer) 1
127.0.0.1:6379> getbit mybit3 0
(integer) 1
127.0.0.1:6379> getbit mybit3 1
(integer) 1
复制代码
HyperLogLogs
什么是基数
基数是一个集合中不重复的元素,例如 A{1,1,2,3,4,4,5} 这个集合的基数是 5
官方说明
超日志(HyperLogLog)是一种概率数据结构,用于统计唯一的事物(从技术上讲,这是指估计集合的基数)。通常,计算唯一项目需要使用与要计数的项目数成比例的内存量,因为您需要记住您在过去看到的元素,以避免多次计数。但是,有一组算法会以内存换取精度:您最终会得到带有标准误差的估计量,在Redis实现的情况下,该误差小于1%。该算法的神奇之处在于,您不再需要使用与所计数项目数成正比的内存量,而是可以使用固定的内存空间!在最坏的情况下为12k字节,如果您的HyperLogLog(从现在开始将它们称为HLL)的元素很少,则使用内存更少。
Redis中的HLL尽管在技术上是不同的数据结构,但被编码为Redis String,因此您可以调用GET来序列化HLL,然后调用SET来将其反序列化回服务器。
然而您并没有真正将项添加到HLL中,因为它的数据结构只存储不含实际元素的状态
使用场景 一个人访问一个网站多次,但是还是算作一个人
传统方式:使用 set 来存储访问的人的 id,但是这样 set 集合中会存储大量的用户 id,我们的目的是计数,不是存储 id。
现在解决方案:使用 hyperloglog 数据类型,因为它不是真正的添加元素到 HLL 中,占用内存很小
pfadd
把一个或多个值添加到数据类型为 hyperLogLogs 的 key 中
127.0.0.1:6379> pfadd hyper a b c d
(integer) 1
复制代码
pfcount
计算一个或多个key中存储的元素的个数
127.0.0.1:6379> pfadd hyper a b c d
(integer) 1
127.0.0.1:6379> pfadd info d g h
(integer) 1
127.0.0.1:6379> pfcount hyper info
(integer) 6
127.0.0.1:6379> pfcount hyper
(integer) 4
复制代码
pfmerge
合并多个 key 中的数据到一个 key
127.0.0.1:6379> pfadd hyper a b c d
(integer) 1
127.0.0.1:6379> pfadd info d g h
(integer) 1
127.0.0.1:6379> pfmerge test hyper info
OK
127.0.0.1:6379> pfcount test
(integer) 6
复制代码
geospatial
官方说明
这个数据类型可以存储地球上地理位置的经纬度信息,能够通过经纬度信息计算出两地之间的距离,能够通过坐标和半径的方式找出范围内的其他地理位置
如果你的程序需要使用 附近的人 的功能,使用 geospatial 数据类型就能做到。
geoadd
添加一个或多个带有经纬度的地理位置
# 格式:geoadd key 经度 维度 地点名称 [经度 维度 地点名称 ...]
127.0.0.1:6379> geoadd geo 120.21201 30.2084 hangzhou 121.48941 31.40527 shanghai
(integer) 2
复制代码
geodist
返回两地之间的距离
127.0.0.1:6379> geoadd geo 120.21201 30.2084 hangzhou 121.48941 31.40527 shanghai
(integer) 2
127.0.0.1:6379> geodist geo hangzhou shanghai km # 最后一个参数指定单位
"180.5896"
复制代码
[图片上传失败...(image-5ae9a6-1602473117944)]
geohash
获取一个或多个地点的 geohash 值,这个 geohash 其实就是地点的经纬度信息经过编码形成的,每个字符串代表唯一的坐标
127.0.0.1:6379> geoadd geo 120.21201 30.2084 hangzhou 121.48941 31.40527 shanghai
(integer) 2
127.0.0.1:6379> geohash geo hangzhou shanghai
1) "wtm7z7r8wv0"
2) "wtw6st1uuq0"
复制代码
geopos
返回一个或多个地理位置的经纬度坐标
127.0.0.1:6379> geoadd geo 120.21201 30.2084 hangzhou 121.48941 31.40527 shanghai
(integer) 2
127.0.0.1:6379> geopos geo hangzhou shanghai
1) 1) "120.21200805902481079"
2) "30.20839995425554747"
2) 1) "121.48941010236740112"
2) "31.40526993848380499"
复制代码
georadius
给定一个坐标作为圆心,给定一个距离作为半径,扫描这个圆范围内的地点(前提是redis中存在)
127.0.0.1:6379> geoadd geo 120.21201 30.2084 hangzhou 121.48941 31.40527 shanghai
(integer) 2
127.0.0.1:6379> geoadd geo 113.27324 23.15792 guangzhou 91.13775 29.65262 xizang
(integer) 2
# 格式:georadius key 经度 维度 半径 单位 [可选项,见官网]
127.0.0.1:6379> georadius geo 120.21201 30.2084 200 km # 以杭州为中心200km为半径扫描
1) "hangzhou"
2) "shanghai"
127.0.0.1:6379> georadius geo 120.21201 30.2084 5000 km # 杭州为中心,5000km为半径扫描
1) "xizang"
2) "guangzhou"
3) "hangzhou"
4) "shanghai"
复制代码
georadiusbymember
这个命令和 georadius
命令一样, 都可以找出位于指定范围内的元素, 但是 georadiusbymember
的中心点是由给定的位置元素决定的, 而不是像 georadius
那样, 需要输入的经度和纬度来决定中心点。
127.0.0.1:6379> geoadd geo 120.21201 30.2084 hangzhou 121.48941 31.40527 shanghai
(integer) 2
127.0.0.1:6379> geoadd geo 113.27324 23.15792 guangzhou 91.13775 29.65262 xizang
(integer) 2
127.0.0.1:6379> georadiusbymember geo hangzhou 200 km
1) "hangzhou"
2) "shanghai"