【Redis笔记】八种数据类型及使用场景
String类型
value可以是String类型,也可以是数字类型(整数、浮点);当遇到incr、decr等操作就会转换成数值型进行计算,此时redisObject的encoding值为int。
不管哪种类型,底层都是字节数组形式存储,只不过编码方式不同。string类型最大空间不能超过512m
命令
设置:set key value [EX seconds] [PX milliseconds] --设置过期时间EX表示秒 PX表示毫秒
设置带过期时间,如果存在就覆盖:SETEX KEY_NAME TIMEOUT VALUE
设置,如果存在就不操作:SETNX key value
批量设置:mset k1 v1 k2 v2 k3 v3
获取:get key
批量获取:mget k1 k2 k3
先get再set:getset key value #获取原来的值,并设置新值
删除:del key
自增:incr key
自增指定步长:incrby key number #例如:incrby num 2 让num每次自增2
浮点自增:incrbyfloat key number
自减:decr key 查看长度:strlen key 截取字符串:getrange key 0 3 追加字符串:append a aaaaaa #如果不存在就相当于set 替换/追加字符串:setrange a 6 “abc”
添加string类型的键值对,前提时这个key不存在,否则不执行:SETNX
添加string类型的键值对,并指定有效期:SETEX
使用场景
场景1.分布式锁
SETNX lockkey 1 ex 10 --返回1证明获取锁成功
---------------------------执行业务操作
DEL lockkey --执行完业务释放锁
SETNX:如果key不存在就添加,返回1;如果key已存在不添加,返回0
场景2.分布式ID、计数器
INCR order:id --自增1
INCRBY order:id 100 --自增100(大量自增操作的场景,可以优化性能)
场景3.防止秒杀重复提交、重复排队
INCR userid --第一次执行返回1,之后执行递增,所以判断是否返回1,如果大于1说明已排队
Hash类型
Hash是最接近关系型数据库结构的数据类型,其value是一个无序字典。
Hash是一个string类型的field、value的映射表。适合存储对象。将一个对象存储在hash类型中会占用更少的内存,并且可以更方便的存取整个对象。Hash结构还可以使你像在数据库中Update一个属性一样只修改某一项属性值。
命令
存储:hset key field1 value1
存储(存在就不创建):hsetnx key field value
存储多个:hmset key field1 value1 field2 value2
获取:hget key field
获取多个字段:hmget key field1 field2
获取所有fied和value: hgetall key
获取所有field:hkeys key
获取所有value:hvals key
删除:hdel key field
获取长度:hlen key
判断field是否存在:hexists key field
获取所有field:hkeys key
获取所有value:hvals key
field加减:hincrby key field 数字
场景
场景1.存储对象
场景2.
List类型
列表,数据结构是双向链表,可以存储列表结构的数据。
特征:有序、元素可重复、插入和删除快、查询速度一般
命令
lpush key value... -- 将一个或多个元素加入列表左侧。如果list不存在就创建list
rpush key value... -- 将一个或多个元素加入列表右侧
lrange key start end -- 范围获取,不删除(案例:获取全部 lrange mylist 0 -1)
lpop key -- 从列表左侧获取一个元素并删除
rpop key -- 从列表右侧获取一个元素并删除
blpop、brpop -- 与lpop和rpop类似,只不过在没有元素时等待指定时间,而不是直接返回nul
lindex key 1 -- 从列表左侧获取索引为1元素,不删除
llen key -- 查看列表长度
lrem key 个数 value -- 移除指定个数的指定值(案例:移除左侧两个值为aa的数据,lrem k 2 v)
lset key 1 value -- 修改指定索引位置的值,如果不存在就会报错
linsert key <before|after> listvalue value --在指定值前面或后面插入值,如果list中有多个指定值,只在第一个前后插入(案例:linsert mylist before 8 10 --在8前面插入10)
使用场景
栈(lpush、lpop)
队列(lpush、rpop)
阻塞队列(LPUSH、BRPOP)
场景1.防止库存超卖:
比如秒杀活动有10个产品,创建10个队列,每个队列存放一个产品,队列元素个数对应产品库存,每个队列元素中存放skuid,如果用户购买就pop一个元素,然后让用户去下单,这样处理不会出现超卖的情况
场景2.公众号:
set类型
集合,和List的区别是Set元素无序且不可重复;
类似HashSet
,相同的对象内容只能在Set中存在一次,后面在添加的对象内容会覆盖已经存在Set中的对象内容
Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存到一个新的集合中。
特征:无序、元素不可重复、查找快、支持交集并集差集等功能
命令
存储:sadd key value [value2...]
获取全部元素:smembers key
是否存在某元素:sismember key value
查看元素个数:scard key
删除集合中的某个元素:srem key value
随机查找:srandmember key [count] -- 加了count参数可以获取多个随机数
随机移除元素:spop key [count]
将指定元素移动到其他set:smove key key2 value --将value从key集合移动到key2集合
差集:sdiff key1 key2 --查找key1中key2不存在的元素
交集:sinter key1 key2
将多个集合合并到一个集合:SUNIONSTORE destination key [key ...]
使用场景
统计访问网站的所有IP(去重)
共同好友(交集)
推荐好友(差集)
抽奖(随机查找)
点赞(微信朋友圈用户A的某条消息的点赞功能,要实现点赞、取消点赞、获取点赞列表、获取点赞用户数量、判断某用户是否点赞过。)
收藏
Zset类型
有序集合,在set的基础上增加一个顺序属性,比如一个存储全班同学成绩的Sorted Sets,其集合value可以是同学的学号,而score就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。
特征:可排序、元素不重复、查询速度快
命令
存储:zadd key score value -- score:分数。如果元素已经存在,就更新score值
获取:zrange key start end [withscores] -- zrange mysortset 0 -1 withscores 获取集合,并带排序
获取通过排序:zrangebyscore key min max [withscores] -- -inf、+inf表示负无穷、正无穷,withscore:附带排序值
获取指定元素score值:zscore key value
获取指定元素排名:zrank key member
统计score值在给定范围内所有元素个数:zcount key min max
按score排序后,获取指定排名范围内的元素:zrange key min max
按score排序后,获取指定score范围内的元素:zrangebyscore key min max
指定元素的score值自增:zincrby key increment member
删除:zrem key value
获取个数:zcard key
差集、交集、并集:zdiff、zinter、zunion
使用场景
场景1.排行榜、热搜榜
场景2.定时任务、处理过期项目(如果有新数据添加时,我们把它加到有序集合中,用时间做排序。开一个服务定时查询,取前十项,时间过期就删除数据。)
场景3.延时队列
拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。
geospatial:(地理位置)
GEO就是Geolocation的简写形式,代表地理坐标。
命令
GEOADD:添加一个或多个地理空间信息,包含:经度(longitude)、纬度(latitude)、值(member)
geoadd china:add 116.378248 39.865275 beijingnanzhan #添加单个(北京南站)
geoadd china:add 116.378248 39.865275 beijingnanzhan 116.42803 39.903738 beijingzhan #添加多个(北京南站、北京站)
GEODIST:计算指定的两个点之间的距离并返回
geodist china:add beijingnanzhan beijingzhan km # km是单位
GEOHASH:将指定member的坐标转为hash字符串形式并返回
GEOPOS:返回指定member的坐标
GEORADIUS:指定圆心、半径,找到该圆内包含的所有member,并按照与圆心之间的距离排序后返回。6.2以后已废弃
GEOSEARCH:在指定范围内搜索member,并按照与指定点之间的距离排序后返回。范围可以是圆形或矩形。6.2.新功能
geosearch china:add frommember beijingzhan byradius 10 km count 10 withdist #北京站为圆心,半径10km以内,10个地址,并带上距离
GEOSEARCHSTORE:与GEOSEARCH功能一致,不过可以把结果存储到一个指定的key。 6.2.新功能
使用场景
附近的人
Hyperloglog
用来统计基数个数,多次add相同值,只记录一个,相比string类型占用内存少。有0.8%的误差。场景:统计UV
是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
命令
pfadd key value # 添加
pfcount key # 统计数量
pfmerge key1 key2 # 合并
Bitmaps:位存储
适合存储只有两个状态的数据,节省内存,一位代表一个数据
命令
setbit key 索引位置 [0 | 1] 添加,案例: setbit sign 0 1
getbit key 索引位置 获取
bitcount key 统计为1的个数
使用场景
一年打卡
登录记录