玖叶教程网

前端编程开发入门

分布式缓存 - Redis基础入门(三)

Redis 五大数据类型(相关命令):https://redis.io/commands/

这里说的数据类型是value的数据类型,key的类型都是字符串。

5种数据类型:

  • redis字符串(String)
  • redis列表(List)
  • redis集合(Set)
  • redis哈希表(Hash)
  • redis有序集合(Zset)

Redis列表(List)

  • redis列表是单键多值。
  • redis列表是简单的字符串列表,按照插入顺序排序。
  • 可以添加一个元素到列表的头部(左边)或者尾部(右边)。
  • 底层实际上是使用双向链表实现。

1、常用命令

1.1、lpush/rpush:从左边或者右边插入一个或多个值

lpush/rpush <key1> <value1> <key2> <value2> ...

示例:

127.0.0.1:6379> flushdb #清空db,方便测试
OK
127.0.0.1:6379> rpush name java spring "springboot" "spring cloud" #列表name的左边
插入4个元素
(integer) 4
127.0.0.1:6379> lrange name 1 2 #从左边取出索引位于[1,2]范围内的元素
1) "spring"
2) "springboot"

1.2、lrange:从列表左边获取指定范围内的值

lrange <key> <star> <stop>

a) 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。

b) 下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1表示列表的第二个元素,以此类推。

c) 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

返回值:

一个列表,包含指定区间内的元素。

示例:

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush course java c c++ php js nodejs #course集合的右边插入6个元素
(integer) 6
127.0.0.1:6379> lrange course 0 -1 #取出course集合中所有元素
1) "java"
2) "c"
3) "c++"
4) "php"
5) "js"
6) "nodejs"
127.0.0.1:6379> lrange course 1 3 #获取course集合索引[1,3]范围内的元素
1) "c"
2) "c++"
3) "php"

1.3、lpop/rpop:从左边或者右边弹出多个元素

lpop/rpop <key> <count>

count:可以省略,默认值为1

lpop/rpop 操作之后,弹出来的值会从列表中删除

值在键在,值亡键亡。

示例:

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush course java c++ php js node js #集合course右边加入6个元素
(integer) 6
127.0.0.1:6379> lpop course #从左边弹出1个元素
"java"
127.0.0.1:6379> rpop course 2 #从右边弹出2个元素
1) "js"
2) "node"

1.4、rpoplpush:从一个列表右边弹出一个元素放到另外一个列表中

rpoplpush source destination

从source的右边弹出一个元素放到destination列表的左边

示例:

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush k1 1 2 3 #列表k1的右边添加3个元素[1,2,3]
(integer) 3
127.0.0.1:6379> lrange k1 0 -1 #从左到右输出k1列表中的元素
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> rpush k2 4 5 6 #列表k2的右边添加3个元素[4,5,6]
(integer) 3
127.0.0.1:6379> lrange k2 0 -1 #从左到右输出k2列表中的元素
1) "4"
2) "5"
3) "6"
127.0.0.1:6379> rpoplpush k1 k2 #从k1的右边弹出一个元素放到k2的左边
"3"
127.0.0.1:6379> lrange k1 0 -1 #k1中剩下2个元素了
1) "1"
2) "2"
127.0.0.1:6379> lrange k2 0 -1 #k2中变成4个元素了
1) "3"
2) "4"
3) "5"
4) "6"

1.5、lindex:获取指定索引位置的元素(从左到右)

lindex key index

返回列表 key 中,下标为 index 的元素。

下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1

表示列表的第二个元素,以此类推。

你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

如果 key 不是列表类型,返回一个错误。

返回值:

列表中下标为 index 的元素。

如果 index 参数的值不在列表的区间范围内(out of range),返回 nil

示例:

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush course java c c++ php #列表course中放入4个元素
(integer) 4
127.0.0.1:6379> lindex course 2 #返回索引位置2的元素
"c++"
127.0.0.1:6379> lindex course 200 #返回索引位置200的元素,没有
(nil)
127.0.0.1:6379> lindex course -1 #返回最后一个元素
"php"

1.6、llen:获得列表长度

llen key

返回列表 key 的长度。

如果 key 不存在,则 key 被解释为一个空列表,返回 0 .

如果 key 不是列表类型,返回一个错误。

示例:

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush name ready tom jack
(integer) 3
127.0.0.1:6379> llen name
(integer) 3

1.7、linsert:在某个值的前或者后面插入一个值

linsert <key> before|after <value> <newvalue>

a) 将值 newvalue 插入到列表 key 当中,位于值 value 之前或之后。

b) 当 value 不存在于列表 key 时,不执行任何操作。

c) 当 key 不存在时, key 被视为空列表,不执行任何操作。

d) 如果 key 不是列表类型,返回一个错误。

返回值:

a) 如果命令执行成功,返回插入操作完成之后,列表的长度。

b) 如果没有找到 value ,返回 -1 。

c) 如果 key 不存在或为空列表,返回 0 。

示例:

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush name ready tom jack #列表name中添加3个元素
(integer) 3
127.0.0.1:6379> lrange name 0 -1 #name列表所有元素
1) "ready"
2) "tom"
3) "jack"
127.0.0.1:6379> linsert name before tom lily #tom前面添加lily
(integer) 4
127.0.0.1:6379> lrange name 0 -1 #name列表所有元素
1) "ready"
2) "lily"
3) "tom"
4) "jack"
127.0.0.1:6379> linsert name before xxx lucy # 在元素xxx前面插入lucy,由于xxx元素不存
在,插入失败,返回-1
(integer) -1
127.0.0.1:6379> lrange name 0 -1
1) "ready"
2) "lily"
3) "tom"
4) "jack"

1.8、lrem:删除指定数量的某个元素

LREM key count value

根据参数 count 的值,移除列表中与参数 value 相等的元素。

count 的值可以是以下几种:

a) count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count。

b) count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count绝对值。

c) count = 0 : 移除表中所有与 value 相等的值。

返回值:

被移除元素的数量。

因为不存在的 key 被视作空表(empty list),所以当 key 不存在时,总是返回 0 。

示例:

127.0.0.1:6379> flushdb #清空db,方便测试
OK
127.0.0.1:6379> rpush k1 v1 v2 v3 v2 v2 v1 #k1列表中插入6个元素
(integer) 6
127.0.0.1:6379> lrange k1 0 -1 #输出k1集合中所有元素
1) "v1"
2) "v2"
3) "v3"
4) "v2"
5) "v2"
6) "v1"
127.0.0.1:6379> lrem k1 2 v2 #k1集合中从左边删除2个v2
(integer) 2
127.0.0.1:6379> lrange k1 0 -1 #输出列表,列表中还有1个v2,前面2个v2干掉了
1) "v1"
2) "v3"
3) "v2"
4) "v1"

1.8、lset:替换指定位置的值

lset <key> <index> <value>

将列表 key 下标为 index 的元素的值设置为 value 。

当 index 参数超出范围,或对一个空列表( key 不存在)进行lset时,返回一个错误。

返回值:

操作成功返回 ok ,否则返回错误信息。

示例:

127.0.0.1:6379> flushdb #清空db,方便测试
OK
127.0.0.1:6379> rpush name tom jack ready #name集合中放入3个元素
(integer) 3
127.0.0.1:6379> lrange name 0 -1 #输出name集合元素
1) "tom"
2) "jack"
3) "ready"
127.0.0.1:6379> lset name 1 lily #将name集合中第2个元素替换为liy
OK
127.0.0.1:6379> lrange name 0 -1 #输出name集合元素
1) "tom"
2) "lily"
3) "ready"
127.0.0.1:6379> lset name 10 lily #索引超出范围,报错
(error) ERR index out of range
127.0.0.1:6379> lset course 1 java #course集合不存在,报错
(error) ERR no such key

2、数据结构

List的数据结构为快速链表quickList。

首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也就是压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。

当就比较多的时候才会改成quickList。因为普通的链表需要的附加指针空间太大,会比较浪费空间,比如这个列表里存储的只是int类型的数,结构上还需要2个额外的指针prev和next。

redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用,这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。

3、应用场景

1、常用分布式数据结构

  • Stack(栈)= LPUSH +LPOR =FILO
  • Queue(队列)= LPUSH + RPOP
  • Blocking MQ(阻塞队列)= LPUSH + BRPOP

2、微博消息和微信公号消息

xx老师关注了小明,备胎说车等大V

  • 1)小明发微博,消息ID为10018

LPUSH msg:{xx老师-ID}10018

  • 2)备胎说车发微博,消息ID为10086

LPUSH msg:{xx老师-ID} 10086

  • 3)查看最新微博消息

LRANGE msg:{xx老师-ID}0 4

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言