数据类型
五大数据类型
String、List、Set、Hash、Zset。
三种特殊数据类型
geospatial、hyperloglog、bitmap
五大数据类型
1.String (get、set)
1 | set key2 abc # 设置值 |
String小结
数据结构是相通的,这些方法在java的字符串中同样也有体现。
目前所学的命令,在jredis中都是一个个的方法。
String类型使用场景:value除了可以设置字符串,还可以设置数字。
- 计数器
- 统计数量:如统计uid为98534的用户粉丝数,uid:98534:follow 123
- 对象缓存存储
2.List列表类型(lpush、rpush、lpop、rpop、lrange)
在Redis里,可以把List玩成栈、队列、阻塞队列。(如把List设置成只能从一边进出,就成了栈)
命令:所有的List命令都是以l开头的(不区分左右的情况下)
1 | # 设置值:lpush(LeftPush),rpush(RightPush) |
List小结
- 它实际上是一个链表,(before 当前值 after)
- left、right都可以插入值
- 如果key不存在,插入前要创建新的链表
- 如果key存在,可新增内容
- 如果移除了所有值,链表就是空链表,也代表不存在
- 在两边插入或改动值,比对中间元素进行操作,效率要高。
用途:
1.消息队列:Lpush Rpop (左边进,右边出)
2.栈:Lpush Lpop (左边进,左边出)
3.关注列表、粉丝列表
3.Set集合类型(sadd、spop、smembers、sunion)
set中的值是不能重复的。
命令:所有的Set命令都是以s开头的
1 | # 添加一个值:sadd |
Set小结
社交网站中,把A用户所有关注的人放在一个集合中,将他的粉丝也放在一个集合中。
那么就能实现共同关注、共同好友功能,以及实现好友推荐(六度分割理论)
交并差集、某时间段去重数据。
4.Hash(Map集合)(hget、hset、hgetall)
存的值是map集合。可以想象成是key-map
,即key-<key, value>
。
本质和String类型没有太大区别,都是简单的key-value
命令:所有的Hash命令都是以h开头的。
1 | # 设置值(field-value:这里不称key,称field) |
Hash小结
存变更的数据:用户信息的保存、经常变动的信息。
Hash适合对象的存储、String适合字符串的存储(String虽然也能存对象,但不是最佳的方式)、多键值对的用户信息。
5.Zset有序集合(zadd、zrange、zrem、zcard)
在Set的基础上 增加了一个值: score。(方便排序用)
1 | # set 与 zset区别 |
Zset小结
比起Set,Zset多了排序功能(显而易见是有序无重复排序)。
排序场景:存储班级成绩表、工资排序表。
带权重判断:如普通消息:score设置为1,重要消息:score设置为2。
排行榜的实现:每几个小时或每天刷新一次。
三种特殊数据类型
1.geospatial(地理位置)
用于定位、附近的人、打车距离计算等。
Redis的Geo在Redis3.2版本就推出了。这个功能可以推算地理位置的信息,比如两地之间的距离。
城市经纬度查询1
城市经纬度查询2
只有6个命令:
- geoadd:将指定的空间位置(经度、纬度、位置)添加到指定的key中。
- geopos:从key里返回 给定位置元素的 经度和纬度。
- geodist:返回两个给定位置之间的距离。
- georadius:以给定的经纬度为中心,找出某一半径内的元素。
- georadiusByMember:找出位于指定范围内的元素,中心点位置由 给定的位置元素决定。
- geohash: 返回一个或多个位置元素的Geohash表示。
geoadd、geopos:添加与获取空间位置
1 | # geoadd key value (这里value内容:经度 纬度 member) |
geodist:计算两位置之间距离
1 | # geodist key member1 member2 单位' |
georadius:以给定的经纬度为中心,找出某一半径内的元素。
如附近的人:首先要获取附近的人的定位。(通过半径来查询)
1 | # georadius key longitude latitude radius 单位 |
georadiusByMember: 找出位于指定范围内的元素,中心点位置由 给定的位置元素决定。
georadius需要填入坐标,而georadiusByMember 需要填已经定义好的位置元素。
1 | # 在china:city中查找 北京方圆1000km 的所有城市 |
geohash: 返回一个或多个位置元素的Geohash表示。
将二维的经纬度转化为一维的hash(可以判断是否为同一地区)
1 | # geohash key member |
Geo
的底层实现原理:其实就是Zset
。所以可以通过
zset
命令来操作Geo
1 | # 查看保存的所有城市 |
2.hyperloglog(基数统计)
什么是基数?
例:A{1, 3, 5, 7, 8} 、B{1, 3, 5}
基数(不重复的元素个数) = 3
简介
Redis2.8.9就跟新了hyperloglog 数据结构。hyperloglog 是用来做基数统计的算法。
优点:占用内存是固定的。(2^64不同元素的基数,至于要用12kb内存。)
缺点:有0.81%的错误率。(对于统计网站访问量,是可以忽略错误率的)
如:统计网页的UV(网站访问量):正确做法:一个人访问此网站多次,还是算作一次访问。
传统方式:用set保存用户的id,因为set不允许重复,此id再次访问就会覆盖原来的。统计set中元素的数量,就可以统计出网站访问次数。
这种方式如果保存大量的用户id,占用内存就会大。而我们的目的是为了计数,而不是保存id。
使用hyperloglog
所有的 hyperloglog命令以pf开头。
1 | # pfadd key member...:一次放一个或多个元素 |
如果允许容错,建议使用Hyperloglog。
如果不允许容错,就使用set 或者自己定义的数据类型即可。
3.bitmap(位图场景)
位存储
统计疫情:000100100 (1表示感染、0表示未感染)
统计用户信息:0010011(活跃、不活跃,或登录、未登录等)
对于上面这些只有两个状态的情况,都可以使用bitmap。
bitmap:位图,是一种数据结构。就是操作二进制位来进行记录(只有0、1两种状态)
1 | # setbit key offset value 在当前key的offset位置,设置值value |