redis学习笔记(三)——五种数据结构的理解和使用

字符串

字符串的结构和适用场景

先看一下字符串的键值结构:
pic1

对于redis来说,所有的key都是字符串类型的,但value的类型各有不同(五种主要数据类型)。

和js一样,数字、二进制、json等等也属于string类型。

字符串的主要使用场景包括缓存、计数器、分布式锁等等。

字符串的常用命令

基本命令
get key
// 获取key对应的value

set key value
// 设置key-value

del key
// 删除key-value

pic2

计数相关的命令(value可以存整形)
incr key
// key自增1,如果key不存在,自增后get(key)=1

decr key
// key自减1,如果key不存在,自减去后get(key)=-1

incrby key k
// key自增k,如果key不存在,自增后get(key)=k

decrby key k
// key自减k,如果key不存在,自减去后get(key)=-k

pic3

上图可以看到,当某key内数据不为整形时,会报错

incr、decr对于网站的计数是非常好用的,如统计访问量、点击量。

set相关命令
set key value
// 不管key是否存在,都设置

setnx key value
// key不存在,才设置

set key value xx
// key存在,才设置

nx其实就相当于增加,xx相当于更新操作。这对于实际使用上也很有帮助。

mget mset 批量操作
mget key1 key2 key3
// 批量获取key 原子操作

mset key1 value1 key2 value2 key3 value3
// 批量设置key-value

这里介绍一下mget和普通get的区别,如果我们要获取n个值,那么实际所花费时间为n次网络时间+n次命令时间
pic4

但如果使用mget,所花费时间为1次网络时间和n次命令时间,耗时大大减少
pic5

当然mget不能一次get无限个,应该适当使用。

另外备注一下,mset也是原子操作,这个命令的使用不会导致一部分数据被修改另外一部分未被修改(中断时)。

其他操作
getset key newvalue
// set key newvalue 并返回旧的value

append key value
// 将value追加到旧的value

strlen ken
// 返回字符串的长度(注意中文,中文占用的不是一个字节)

pic6

incrbyfloat key 3.5
// 增加key对于的浮点数 3.5

getrange key start end
// 获取字符串指定下标所有的值

setrange key index value
// 设置指定下标所有对应的值

pic7

hash

hash的键值结构

hash自然也是key-value类型。key值为字符串,value则分为两个:field和value。vield代表属性,value代表对应的值。

其实就相当于直接存储了一个对象,我们可以直接向这个对象添加属性。

如果是string,string储存对象,那么常用的方法是将对象序列化为json格式存储,需要增加属性则取出来,反序列化后添加属性再序列化存进去。

数据结构如下:

pic8

可以理解为存储了一张表:

pic9

hash的特点

  • smallredis。可以这么理解,redis本来就是一个key-value类型,hash又是一个key-value。
  • field不能相同,value可以相同。

重要API

H:所有哈希命令都以h开头。

hget key field
// 获取hash key对应的field的value

hset key field value
// 设置hash key对应field的value

hdel key field
// 删除hash key对应field的value

pic10

hexists key field
// 判断hash key是否有field

hlen key
// 获取hash key field的数量
hmget key field1 field2……
// 批量获取hash key的一批field对应的值

hmset key field1 value1 field2 value2……
// 批量设置hash key的一批field value

效果其实和mget、mset一样

hgetall key
// 返回hash key对应所有的field和value

hvals key
// 返回hash key对应所有field的value(只返回值)

hkeys key
// 返回hash key对应所有field

pic11

同样的,小心使用hgetall。牢记redis是单线程。

hsetnx key field value
// 设置hash key对应field的value(如field已经存在,则失败)

hincrby key field intCounter
// hash key对应的field的value自增intCounter

hincrbyfloat key field floatCounter
// hincrby浮点数版

string vs hash

相似的api自然不用多说:
pic12

以存储一个用户的信息为例子,如果我们使用string类型,那么会将其信息序列化后存入redis。但这样每次增加删除都需要进行序列化和反序列化的操作。

pic13

另外一个存储方法,就是每个key代表一个属性。只是这样每个对象就分离开了,不是一个整体。相应的,它可以单独操作某属性。

pic14

而用hash就比较直观了,能满足上述两个优点,而且实际是能够节省很多内存的:

pic15

3种方案的优缺点:

  1. 方案一——string存储序列化数据:优点:编程简单、可能节约内存;缺点:序列化开销、设置属性要操作整个数据。
  2. 方案二——string分开储存属性:优点:直观、可以部分更新;缺点:内存占用较大、key较为分散。
  3. 方案三——hash:优点:直观、节省空间、可以部分更新;缺点:编程较为复杂,且过期时间不好设置。无法直接办到对hash中某个属性添加过期时间的设置。

列表

列表的key实际上就是一个常见的有序队列。列表是有序的可以重复的数据结构,并且可以在两边插入或是弹出。

pic16

重要api

列表的大多api都是以l为开头。

rpush key value1 value2……
// 从列表右端插入值

lpush key value1 value2……
// 从列表左边插入值

linsert key before|after value newValue
// 在list指定的值前|后插入newValue

lpop key
// 从列表左侧弹出一个item

rpop key
// 从列表右侧弹出一个item

lrem key count value
// 根据count值,从列表中删除所有value相等的值。
// count > 0,从左到右,删除最多count个value相等的值
// count < 0,从右到左,删除最多Math.abs(count)个value相等的值
// count=0,删除所有value相等的值

ltrim key start end
// 按照索引范围修建列表

lrange key start end
// 获取列表制定索引范围所有item,包含end

lindex key index
// 获取列表指定索引的item

llen key
// 获取列表长度

lset key index newValue
// 设置列表指定索引值为newValue

其他

blpop/brpop key timeout
// lpop/rpop 阻塞版本,timeout是阻塞超时时间,timeout=0为永远不阻塞。比如要取一个空队列,lpop直接返回,但是blpop会保持等待,直到有数据或是时间到了。

实际使用

比如timeline(按时间排序的微博),就可以用列表来进行存储。

集合set

集合的数据结构

对于集合,key仍然是字符串,但是value就是一个集合,它会将所有字符串做一个组合。

pic17

集合支持集合间的api。集合不允许插入重复元素。集合是无序的。

集合的常用API

集合命令以s开头。

sadd key element
// 向集合key添加element(如果element已经存在,添加失败)

srem key element
// 将集合key中的element移除掉

scard key
// 计算集合大小

sismember key element
// 判断value是否在集合中

srandmember key count
// 从集合中随机挑count个元素

spop key
// 从集合中随机弹出一个元素

smembers key
// 获取集合所有元素(无需返回,小心使用)

集合可以用来使用于抽奖、点赞系统、tag系统等。

集合间api:

sdiff key1 key2
// 得到差集

sinter key1 key2
// 得到交集

sunion key1 key2
// 得到并集

sdiff|sinter|sunion + store destkey
// 将对于得到的集合保存在destkey中

有序集合

有序集合是一种比较新的结构,平常接触较少。

特点和数据结构

有序集合的value也为两部分,分为score和value。它按照score来进行一个排序。

pic18.

集合和有序集合的区别,具体可以用如下图所示:

pic19

列表和有序集合的区别,具体可以用如下图所示:

pic20

重要api

有序集合都是以z开头的。

zadd key score element
// 添加score和element(score可以重复,element不能重复)

zrem key element(可以是多个)
// 删除元素

zscore key element
// 返回元素的分数

zincrby key increScore element
// 增加或减少元素的分数

zcard key
// 返回元素的总个数

zrange key start end
// 返回指定索引范围内的升序元素(索引指的是按照分值排序得到的排名)

zrangebyscore key minScore maxScore
// 返回指定分数范围内的升序元素

zcount key minScore maxScore
// 返回有序集合内在指定分数范围内的个数

zremrangebyrank key start end
// 删除指定排名内的升序元素

zremrangebyscore key minScore maxScore
// 删除指定分数内的升序元素

实际使用

有序集合比较常见的使用场景为排行榜

 [前端经典题目分析] ['1', '2', '3'].map(parseInt) what & why ?
redis学习笔记(二)——基本API的理解和使用 
上一篇:[前端经典题目分析] ['1', '2', '3'].map(parseInt) what & why ?
下一篇:redis学习笔记(二)——基本API的理解和使用


如果我的文章对你有帮助,或许可以打赏一下呀!

支付宝
微信
QQ