三种特殊数据类型
1、Geospatial
这个数据类型是与地图相关的,通过传入经纬度定位一个地域!
基本命令
1.1、添加,获取信息
127.0.0.1:6379> geoadd china:city 116.33 39.89 beijing # 添加城市经纬度
(integer) 1
127.0.0.1:6379> geoadd china:city 121.48 31.24 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 113.22 23.17 guangzhou
(integer) 1
127.0.0.1:6379> geoadd china:city 114.06 22.54 shenzhen
(integer) 1
127.0.0.1:6379> geoadd china:city 114.17 22.28 xianggang
(integer) 1
127.0.0.1:6379> geoadd china:city 113.08 28.25 changsha
(integer) 1
127.0.0.1:6379> geoadd china:city 120.21 30.25 hangzhou
(integer) 1
127.0.0.1:6379> geoadd china:city 106.55 29.56 chongqing
(integer) 1
127.0.0.1:6379> GEOPOS china:city beijing # 返回该城市的经纬度
1) 1) "116.3299986720085144"
2) "39.89000061669732844"
1.2、获取两地的距离
127.0.0.1:6379> GEODIST china:city beijing shanghai km # 返回两地的至直线距离,单位是km
"1068.4915"
127.0.0.1:6379> GEODIST china:city beijing guangzhou km
"1882.5799"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1500 km # 返回以北京为中心,半径为1500km内包含的城市members
1) "chongqing"
2) "changsha"
3) "hangzhou"
4) "shanghai"
5) "beijing"
注意:经度 longitudes 的范围为-180到180度。纬度 latitudes 的范围为 -85.05112878 to 85.05112878 度。 ,一但设置超过了这两个值的任意一个,那么将会抛出异常,执行失败!
Geospatial的应用场景
我们微信共享位置的时候,会显示您与其他用户的直线距离,那么这个效果可以通过Geospatial来实现,我们可以获取对方的定位信息(前提是对方开启了定位,并且向国家授权定位信息),那么将两人的经纬度存入Geospatial中,再调用GEODIST指令计算出来两人的距离,显示给前端即可!
4.2、Hyperloglog
这个特殊的数据类型是用来统计基数的,底层实现了基数算法,那什么是基数?
假如有两个集合A{1,2,3,4,5,6,7,8,7},B{1,2,3,4,5,6,7}
那么基数就是1,2,3,4,5,6,7这七个数字,总的来说,基数就是不重复的数字!
基本指令
127.0.0.1:6379> PFADD hpf a b c b d e f c c # 添加值
(integer) 1
127.0.0.1:6379> PFADD abc e f g h i j a b e
(integer) 1
127.0.0.1:6379> PFCOUNT hpf # 统计出集合hpf的基数个数
(integer) 6
127.0.0.1:6379> PFCOUNT hpf abc # 统计出这两个集合的基数个数
(integer) 10
127.0.0.1:6379> PFMERGE res hpf abc # 将这个基数集合结合成一个集合
OK
127.0.0.1:6379> PFCOUNT res
(integer) 10
Hyperloglog的应用场景
网页的UV(UserView),一个人访问多次,但是还是计算一次的访问
有些网站、视频的UV可能会被恶意的刷热度,那么为了防止这种情况,一个用户观看多次视频,网站就只算一次的访问,因为用户的id是唯一不变的,我们可以用用户的id作为基数,当访问后,放这个Hyperloglog集合中添加此元素,那么该用户下次访问后,热度就会不变!
传统的做法是用String类型的set方法,每当用户访问的时候,就直接set一个用户id,然后获取这个集合的值即可,因为我们访问的次数记录的是数量,而不是用户的id,一味的存储用户id,没有实际的作用,而且还浪费大量的空间内存,因为有些用户id可能是UUID,一大长的字符串,非常消耗内存
那么我们使用Hyperloglog,其中一个优点就是节省内存,其占用的内存是固定的,2^64不同的元素基数,只需要12kb的内存,如果从内存角度来比较的话Hyperloglog绝对是首选!!!!
4.3、BitMap
位图
用二进制来存储数据,0和1
基本命令
127.0.0.1:6379> setbit mybit 0 1 # 给bitMap设置值,注意最后一个参数必须填0或者1
(integer) 0
127.0.0.1:6379> setbit mybit 1 0
(integer) 0
127.0.0.1:6379> setbit mybit 2 1
(integer) 0
127.0.0.1:6379> setbit mybit 3 1
(integer) 0
127.0.0.1:6379> setbit mybit 4 0
(integer) 0
127.0.0.1:6379> BITCOUNT mybit # 获取位图中为1的个数
(integer) 3
127.0.0.1:6379> GETBIT mybit 0 # 获取特定偏移量的位
(integer) 1
127.0.0.1:6379> GETBIT mybit 4
(integer) 0
127.0.0.1:6379> BITPOS mybit 0 # 返回位为0的最开始下标
(integer) 1
127.0.0.1:6379> BITPOS mybit 1 # 返回位为1的最开始下标
(integer) 0
除了这些基本命令,我们还可以利用位图存储一些数据,因为官网上说二进制传输时安全的,利用String类型的get方法获取二进制中的数据,因为其是利用二进制进行传输的!!
# 那么8位一个字节,又因为Redis是从0开始的,那么0-7代表一个字节,8-15代表一个字节,依次类推
# 现在这个二进制数据位 00110100 00110010
127.0.0.1:6379> setbit mybit 2 1
(integer) 0
127.0.0.1:6379> setbit mybit 3 1
(integer) 0
127.0.0.1:6379> setbit mybit 5 1
(integer) 0
127.0.0.1:6379> setbit mybit 10 1
(integer) 0
127.0.0.1:6379> setbit mybit 11 1
(integer) 0
127.0.0.1:6379> setbit mybit 14 1
(integer) 0
# 通过String类型的get方法可以获取到对应的值
# 因为前8位为00110100,ASCII码对应为为字符4,那么后8位为00110010,ASCII码对应为为字符2,组合起来就是"42"!
127.0.0.1:6379> get mybit
"42"
BitMap的应用场景
因为BitMap只能存储两种情况,0和1,那么我们可以用它来记录一些打卡情况,像是上班打卡,微信打卡等情况都可以使用它来做!
例如:
# 其中我们约定0-6为星期一到星期六,那么我们可以使用0和1位图来表示此人当前有没有打卡!
127.0.0.1:6379> SETBIT mybit 0 1
(integer) 0
127.0.0.1:6379> SETBIT mybit 1 0
(integer) 0
127.0.0.1:6379> SETBIT mybit 2 1
(integer) 0
127.0.0.1:6379> SETBIT mybit 3 1
(integer) 0
127.0.0.1:6379> SETBIT mybit 4 1
(integer) 0
127.0.0.1:6379> SETBIT mybit 5 1
(integer) 0
127.0.0.1:6379> SETBIT mybit 6 0
(integer) 0
# 打卡了5天!因为bitcount是记录1的!
127.0.0.1:6379> BITCOUNT mybit
(integer) 5
那么三大特殊数据类型就介绍到这里了,大家可以通过它们的特性应用在不同的地方,如果错误请各位大佬指出!!!!