一、数据类型
Redis本身就是一个Map,key部分恒为字符串类型,value部分类型可变,Redis数据类型指value部分的数据类型,主要有string、hash、list、set和sorted_set,实现上分别类似于String、HashMap、LinkedList、HashSet和TreeSet。
二、String类型
-
存储结构图
-
存储内容:
通常使用字符串,但如果是整数字符串也能够作为数字操作 -
7个基本操作
添加/修改:set key value
获取:get key
删除:del key
添加多个:mset key1 value1 key2 value 2
获取多个数据:mget key1 key2
获取数据字符长度:strlen key
追加信息到原始信息后部:append key value -
操作优化
①多数据使用mset命令,数据量少可以使用set命令
②数据量多的时候考虑对数据进行分割然后再进行mset -
应用场景
- 数据库分表操作需要实现主键id自增且唯一,可以使用Redis来生成自增且唯一的id。
这是因为Redis采用单线程执行,所有操作都是原子性的,命令逐个执行不会受并发影响。
Tips:如果类型不是整数或者超范围(Long的最大值)将会出错。
指定数字key + 1:incr key
指定数字key - 1:decr key
指定数字key + folatn:incrbyfloat key folatn
指定数字key + n :incrby key n
指定数字key - n :decrby key n
- 设置具有生命周期的数据,比如Token/ip访问间隔/投票间隔
setex key seconds value
psetex key milliseconds value
- 博客大V粉丝数量等实时变化的数据
key设为大V用户id,value数据用string类型存储JSON格式数据,或者key使用字符串拼接方式,value只存储数字。两种方式各有优缺,第二种更适用于需要实时的数据。
- 数据操作注意事项
- 数据操作不成功的反馈与数据正常操作之间的差异
①表示结果成功- (integer)0 -> false 失败
- (integer)1 -> true 成功
②表示运行结果值 - (integer)3 -> 3 3个
- (integer)1 -> 1 1个
- 数据未获取到
(nil) 等同于 null - 数据最大存储量
512MB - 数值计算范围
java中long类型范围,64位长
三、Hash类型
-
作用:对象类数据的存储如果需要频繁更新的话,string类操作效率不高。同一个对象的多个属性如果用JSON来存需要对JSON数据进行解析,如果用字符串拼接存同一对象多个数据key重复严重,因此此时Hash就体现了价值。
-
存储结构图
-
存储内容
对一系列存储的数据进行编组,常应用于存储对象信息。value保存有多个键值对(field-value)数据。底层使用哈希表实现。
Tips:如果field数量少,存储结构优化为类数组结构,如果field数量较多,存储结构使用HashMap结构。 -
基本操作
①添加/修改数据:hset key field value
②获取数据:hget key field ; hgetall key
③删除数据:hdel key field1 [field2 ···]
④添加/修改多个数据:hmset key filed1 value1 field2 value ···
⑤获取多个数据:hmget key filed1 field 2 ···
⑥获取hash字段数:hlen key
⑦获取哈希表中是否存在指定字段:hexists key field -
扩展操作
- 获取哈希表中所有字段名或字段值:
hkeys key ; hvals key - 设置指定字段的数值数据增加指定范围的值:
hincrby key field increment
hincrbyfloat key field increment - 如果当前已存在该数据则set失败,否则成功
hsetnx key field value
- 应用场景
- 电商网站购物车设计与实现
- 用户id作为key,商品字段拼接字段名编号作为field,字段数据作为value,共有数据独立为hash
- 全选hgetall,删除hdel,取数量hget,增加数量hincrby,商品总数hlen
- 电商app抢购限量商品
key存商家id,field存商品id,value存商品数量,降值使用hincrby key field 负数 - 抢购、限购、限量发放优惠券、激活码等业务的数据存储设计
- 操作注意事项
①hash类型下的value只能存字符串,不能存其他数据类型,不存在嵌套现象
②数据未获取到返回(nil)
③每个hash最多可以从存储2^32-1个键值对
④hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性,但hash设计初衷不是为了存储大量对象而设计的,尤其不可将hash作为对象列表使用
⑤hgetall可以获取全部属性,但如果内部field过多,遍历整体数据效率会降低,可能称为数据访问瓶颈
四、list类型
- 作用:存储多个数据,并对数据进入存储空间的顺序进行区分,底层使用双向链表存储结构实现。
- 基本操作
①添加/修改数据:
lpush key value1 [value2 ···];
rpush key value1 [value2 ···];
②获取数据:
范围数据:lrange key start索引 stop索引;(0代表开头,-1代表倒数第一个元素下标)
单个数据:lindex key index;
数据长度:llen key;
③获取并移除数据
lpop key;
rpop key; - 扩展操作
- 阻塞式数据获取:规定时间内获取并移除数据:
- blpop key1 [key2] timeout
- brpop key1 [key2] timeout
- 删除指定数据
- lrem key count value;(count为删除个数,value为删除数据)
- 应用场景
- 主要应用与具有操作先后顺序的数据控制;使用队列模型解决多路信息汇总合并的问题;使用栈模型解决最新消息的问题
- 微信点赞,实时更新点赞情况,点赞有顺序,期间有人取消点赞
- twitter、微博个人用户关注列表,最近关注的粉丝排在前面
- 新闻资讯按发布时间展示
- 多台日志服务器,想要按顺序输出所有日志,可以将日志发往Redis中value为list类型的key,然后非日志机获取list中的有序日志数据。
- 注意事项
① list中保存的数据都是string类型
② 数据容量最多为2^32-1个元素
③ list有索引的概念,获取全部数据操作的end索引为-1
④ list可对数据进行分页操作,通常第一页信息来自list,第二页及更多的信息通过数据库形式加载
五、set类型
- 作用:能够存储大量数据,在查询方面提供更高的效率。使用存储结构与hash存储结构相同,以实现高效查询,但是仅存储键,不存储值,且值不可重复(即field为数据,value为null)。
- 存储结构图
-
基本操作
①添加数据:sadd key member1 [member2]
②获取全部数据:smembers key
③删除数据:srem key member1 [member2]
④获取集合数据总量:scard key
⑤判断集合中是否包含指定数据:sismember key member -
扩展操作
① 随机获取集合中指定数量的数据,不移出集合
srandmember key [count]
② 随机获取集合中某个数据,移出集合
spop key
③ 求两个集合的交、并、差集
交集:sinter key1 [key2]
并集:sunion key1 [key2]
差集:sdiff key1 [key2]
④ 求两个集合交、并、差集并存储到指定集合中
sinterstore destinationKey key1 [key2]
sunionstore destinationKey key1 [key2]
sdiffstore destiontionKey key1 [key2]
例子:sinterstore set3 set1 set2,将set1∩set2结果存入set3
⑤ 将指定数据从原始集合中移动到目标集合中:
smove sourceKey destinationKey member
例子:smove set2 set1 member1 将set2中的member1数据移动到set1中, -
应用场景
- 用于随机推送类信息检查,例如热点歌单推荐,热点新闻推荐,个性歌单,应用APP推荐等。
- srandmember key [count] 用于可重复随机推送
- spop key 用于随机推送,且只推送一次
- 可利用集合交、并、差集进行同类信息的关联搜索
- sinter用于显示共同关注、共同好友
- sdiff显示不同好友,可用户好友推荐
- 统计网站PV(访问量)、UV(独立访客)、IP(独立IP)
- PV:网站被访问次数,可通过刷新网页提高访问量。(用string类型更合适)。
- UV:网站被不同用户访问的次数,通过cookie统计访问量,相同用户切换ip访问,UV不变
- IP:网站被不同IP地址访问的总次数。
- 黑名单与白名单实现
- 操作注意事项
① set不允许重复数据,重复添加已存在数据将会失败且不会覆盖
② set虽然与hash结构相同,但不能使用hash的命令进行操作
六、sorted_set类型
-
作用:可通过数据自身特征进行排序,有利于数据的展示。存储结构为set基础上加上了可排序字段score,排序字段数据只有排序特征的意义。
-
存储结构图:
-
基本操作
① 添加数据:zadd key score1 member1 [score2 member2]
② 获取全部数据可带score值
zrange key startIndex stopIndex [WITHSCORES] (正向:升序)
zrevrange key start stop WITHSCORES
③ 按条件获取数据
zrangeby score key min max [WITHSCORES] [LIMIT] (limit可用于分页)
zrevrangebyscore key max min [WITHSCORES]
④按条件删除数据
zremrangebyrank key start stop (按排序顺序删除)
zremrangebyscore key min max(按排序特征值删除)
⑤获取集合数据总量
zcard key
zcount key min max
⑥集合交、并操作
zinterstore destinationKey numkeys key [key ···]
zunionstore destinationKey numkeys key [key···] (numkeys为合并key的数量,后面接numkeys个key名,可进行max等聚集操作)
Tips:min/max用于限定搜索查询条件;start/stop用于限定查询范围,作用于索引;offset/count用于限定查询范围,作用于查询结果,表示开始位置和数据总量;
-
扩展操作
①获取数据对应得索引(排名-1)
zrank key member
zrevrank key member
②score值获取与修改
zscore key member
zincrby key increment member -
应用场景
- 歌单排行榜,电影排行榜,票数排行榜等
- 使用zrank、zscore与zincrby
- 限时VIP、网站定期开启投票并限时进行等会过期的信息
- 将处理时间记录为score值,利用排序功能处理执行先后
- 定时任务执行顺序管理或任务过期管理
- 带权重的任务队列/消息队列
- 使用score记录权重,多权重组合为同一个score值,注意需要对齐位长
- 注意事项
①score保存数据存储空间为64为,整数范围为-2^32 ~ 2^32-1
②score保存得数据也可以是一个双精度得double值,但可能丢失精度,使用时要谨慎。比如0.5、0.25、0.125可精准描述,但0.3、0.7等不能精准描述会丢失精度,导致排序不符合预期。
③sorted_set底层存储基于set结构,不存在重复数据。如果添加重复数据,虽返回integer0但score值将被覆盖,而set中重复添加直接返回integer0。