Redis - 3 ( 10000 字 Redis 入门级教程 )

一: List 列表

列表类型用于存储多个有序的字符串,a、b、c、d、e 五个元素从左到右组成一个有序列表,其中每个字符串称为元素。列表最多可以存储 2³² - 1 个元素。在 Redis 中,可以对列表的两端进行插入(push)和弹出(pop),还可以获取指定范围的元素列表或指定索引的元素。作为一种灵活的数据结构,列表既可以充当栈,也可以充当队列,在实际开发中有着广泛的应用场景,List 的特点如下:

特点描述
元素有序列表中的元素是有序的,可以通过索引下标获取指定元素或范围内的元素。例如,lindex user:1:messages 4 获取第 5 个元素,lindex user:1:messages -1 获取倒数第 1 个元素。
区分获取和删除的操作获取和删除操作是区分的。例如,lrem 1 b 会从列表中删除从左数第 1 个 b,导致列表长度从 5 变为 4;而 lindex 4 只会获取第 5 个元素,不会改变列表长度。
元素允许重复列表中的元素可以重复,例如图 2-21 所示,列表中包含两个相同的元素 a。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.1 常用命令

1.1.1 LPUSH

LPUSH 命令用于将一个或多个元素从左侧插入到列表中(头插)。返回值为插入后列表的长度。

LPUSH key element [element ...]
redis> LPUSH mylist "world"
(integer) 1

redis> LPUSH mylist "hello"
(integer) 2

redis> LRANGE mylist 0 -1
1) "hello"
2) "world"

1.1.2 LPUSHX

LPUSHX 命令用于在指定的 key 存在时,将一个或多个元素从左侧插入到列表中(头插)。如果 key 不存在,则直接返回。返回值为插入后列表的长度。

LPUSHX key element [element ...]
redis> LPUSH mylist "World"
(integer) 1

redis> LPUSHX mylist "Hello"
(integer) 2

redis> LPUSHX myotherlist "Hello"
(integer) 0

redis> LRANGE mylist 0 -1
1) "Hello"
2) "World"

redis> LRANGE myotherlist 0 -1
(empty array)

1.1.3 RPUSH

RPUSH 命令用于将一个或多个元素从右侧插入到列表中(尾插)。返回值为插入后列表的长度。

RPUSH key element [element ...]
redis> RPUSH mylist "world"
(integer) 1

redis> RPUSH mylist "hello"
(integer) 2

redis> LRANGE mylist 0 -1
1) "world"
2) "hello"

1.1.4 RPUSHX

RPUSHX 命令用于在指定的 key 存在时,将一个或多个元素从右侧插入到列表中(尾插)。返回值为插入后列表的长度。

RPUSHX key element [element ...]
redis> RPUSH mylist "World"
(integer) 1

redis> RPUSHX mylist "Hello"
(integer) 2

redis> RPUSHX myotherlist "Hello"
(integer) 0

redis> LRANGE mylist 0 -1
1) "World"
2) "Hello"

redis> LRANGE myotherlist 0 -1
(empty array)

1.1.5 LRANGE

LRANGE 命令用于获取列表中从 start 到 end 区间(左闭右闭)的所有元素。返回值为指定区间内的元素列表。

LRANGE key start stop
redis> RPUSH mylist "one"
(integer) 1

redis> RPUSH mylist "two"
(integer) 2

redis> RPUSH mylist "three"
(integer) 3

redis> LRANGE mylist 0 0
1) "one"

redis> LRANGE mylist -3 2
1) "one"
2) "two"
3) "three"

redis> LRANGE mylist -100 100
1) "one"
2) "two"
3) "three"

redis> LRANGE mylist 5 10
(empty array)

1.1.6 LPOP

LPOP 命令用于从列表左侧移除并返回第一个元素(头删)。返回值为移除的元素,若列表为空则返回 nil。

LPOP key
RPUSH mylist "one" "two" "three" "four" "five"
(integer) 5

LPOP mylist
"one"

LPOP mylist
"two"

LPOP mylist
"three"

LRANGE mylist 0 -1
1) "four"
2) "five"

1.1.7 RPOP

RPOP 命令用于从列表右侧移除并返回最后一个元素(尾删)。返回值为被移除的元素,若列表为空则返回 nil。

RPOP key
redis> RPUSH mylist "one" "two" "three" "four" "five"
(integer) 5

redis> RPOP mylist
"five"

redis> LRANGE mylist 0 -1
1) "one"
2) "two"
3) "three"
4) "four"

1.1.8 LINDEX

LINDEX 命令用于获取列表中指定索引位置(从左数)的元素。返回值为对应的元素,若索引位置不存在则返回 nil。

LINDEX key index
redis> LPUSH mylist "World"
(integer) 1

redis> LPUSH mylist "Hello"
(integer) 2

redis> LINDEX mylist 0
"Hello"

redis> LINDEX mylist -1
"World"

redis> LINDEX mylist 3
(nil)

1.1.9 LINSERT

LINSERT 命令用于在列表的指定位置插入元素。返回值为插入后列表的长度。

LINSERT key <BEFORE | AFTER> pivot element
redis> RPUSH mylist "Hello"
(integer) 1

redis> RPUSH mylist "World"
(integer) 2

redis> LINSERT mylist BEFORE "World" "There"
(integer) 3

redis> LRANGE mylist 0 -1
1) "Hello"
2) "There"
3) "World"

1.1.10 LLEN

LLEN 命令用于获取列表的长度。返回值为列表的长度。

LLEN key
redis> LPUSH mylist "World"
(integer) 1

redis> LPUSH mylist "Hello"
(integer) 2

redis> LLEN mylist
(integer) 2

1.1.11 阻塞版本命令

BLPOP 和 BRPOP 是 LPOP 和 RPOP 的阻塞版本,功能与对应的非阻塞版本基本相同,不同之处在于:

特点描述
有元素时表现一致当列表中有元素时,阻塞版本与非阻塞版本的表现一致,直接弹出元素。
无元素时的表现当列表中无元素时,非阻塞版本立即返回 nil,而阻塞版本会根据 timeout 阻塞一段时间,此期间 Redis 可执行其他命令,但执行该命令的客户端处于阻塞状态。
多键操作如果命令设置了多个键,将从左到右依次遍历,一旦某个键对应的列表有元素可弹出,命令立即返回。
并发情况下的处理如果多个客户端同时对同一个键执行 pop 操作,最先执行命令的客户端将获得弹出的元素。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.1.12 BLPOP

BLPOP 命令是 LPOP 的阻塞版本。返回值为取出的元素,若超时或列表为空则返回 nil。

BLPOP key [key ...] timeout
redis> EXISTS list1 list2
(integer) 0

redis> RPUSH list1 a b c
(integer) 3

redis> BLPOP list1 list2 0
1) "list1"
2) "a"

1.1.13 BRPOP

BRPOP 命令是 RPOP 的阻塞版本。返回值为取出的元素,若超时或列表为空则返回 nil。

BRPOP key [key ...] timeout
redis> DEL list1 list2
(integer) 0

redis> RPUSH list1 a b c
(integer) 3

redis> BRPOP list1 list2 0
1) "list1"
2) "c"

1.1.14 命令小结

命令时间复杂度描述
rpush key value [value …]O(k),k 是元素个数从右侧插入一个或多个元素
lpush key value [value …]O(k),k 是元素个数从左侧插入一个或多个元素
linsert key beforeafter pivot valueO(n),n 是 pivot 距离头尾的距离
lrange key start endO(s+n),s 是 start 偏移量,n 是范围获取指定范围的元素列表
lindex key indexO(n),n 是索引的偏移量获取指定索引位置的元素
llen keyO(1)获取列表长度
lpop keyO(1)从左侧弹出第一个元素
rpop keyO(1)从右侧弹出最后一个元素
lrem key count valueO(k),k 是元素个数删除列表中指定值的元素
ltrim key start endO(k),k 是元素个数截取指定范围的列表
lset key index valueO(n),n 是索引的偏移量修改指定索引位置的元素值
blpop / brpopO(1)从列表两端阻塞弹出元素

1.2 内部编码

列表类型的内部编码有两种:

内部编码类型使用条件描述
ziplist当列表元素个数小于 list-max-ziplist-entries(默认 512 个),且每个元素长度小于 list-max-ziplist-value(默认 64 字节)时使用。使用紧凑的内存结构,减少内存消耗。
linkedlist当列表类型不满足 ziplist 条件(如元素个数过多或元素长度过大)时使用。使用链表结构,支持更复杂的操作。
  1. 当元素个数较少且没有大元素时,内部编码为 ziplist:
127.0.0.1:6379> rpush listkey e1 e2 e3
OK

127.0.0.1:6379> object encoding listkey
"ziplist"
  1. 当元素个数超过 512 时,内部编码为 linkedlist:
127.0.0.1:6379> rpush listkey e1 e2 e3 ... 省略 e512 e513
OK

127.0.0.1:6379> object encoding listkey
"linkedlist"
  1. 当某个元素的长度超过 64 字节时,内部编码为 linkedlist:
127.0.0.1:6379> rpush listkey "one string is bigger than 64 bytes ... 省略 ..."
OK

127.0.0.1:6379> object encoding listkey
"linkedlist"

1.3 使用场景

1.3.1 消息队列

Redis 可以通过 lpush 和 brpop 命令组合实现经典的阻塞式生产者-消费者模型。生产者客户端使用 lpush 命令从列表左侧插入元素,多个消费者客户端通过 brpop 命令以阻塞方式从队列中“争抢”队尾元素。通过多个客户端的协作,可以实现消费的负载均衡和高可用性。

在这里插入图片描述

1.3.2 分频道的消息队列

Redis 也可以通过 lpush 和 brpop 命令配合使用,通过不同的键来模拟频道的概念。不同的消费者可以使用 brpop 命令监听不同的键,从而实现订阅不同频道的功能。

在这里插入图片描述

二: Set 集合

集合类型用于保存多个字符串类型的元素,与列表类型不同,集合具有以下特点:元素之间是无序的;元素不允许重复。一个集合最多可以存储 2^32 - 1 个元素。Redis 不仅支持集合内的增删查改操作,还支持集合之间的交集、并集和差集操作。合理利用集合类型,可以高效解决实际开发中的许多问题。

在这里插入图片描述

2.1 常用命令

2.1.1 SADD

SADD 命令用于将一个或多个元素添加到集合中。注意,集合中不能存在重复元素,重复的元素将不会被添加。返回值为本次成功添加的元素个数。

SADD key member [member ...]
redis> SADD myset "Hello"
(integer) 1

redis> SADD myset "World"
(integer) 1

redis> SADD myset "World"
(integer) 0

redis> SMEMBERS myset
1) "Hello"
2) "World"

2.1.2 SMEMBERS

SMEMBERS 命令用于获取集合中的所有元素。注意,集合中的元素是无序的。返回值为集合中所有元素的列表。

SMEMBERS key
redis> SADD myset "Hello"
(integer) 1

redis> SADD myset "World"
(integer) 1

redis> SMEMBERS myset
1) "Hello"
2) "World"

2.1.3 SISMEMBER

SISMEMBER 命令用于判断一个元素是否存在于集合中。返回值:1 表示元素在集合中;0 表示元素不在集合中或集合不存在。

SISMEMBER key member
redis> SADD myset "one"
(integer) 1

redis> SISMEMBER myset "one"
(integer) 1

redis> SISMEMBER myset "two"
(integer) 0

2.1.4 SCARD

SCARD 命令用于集合中元素的数量。返回值为集合中元素的个数。

SCARD key
redis> SADD myset "Hello"
(integer) 1

redis> SADD myset "World"
(integer) 1

redis> SCARD myset
(integer) 2

2.1.5 SPOP

SPOP 命令用于从集合中随机删除并返回一个或多个元素。由于集合内元素是无序的,因此返回的元素是随机的,具体取出哪个元素是未定义的行为。

SPOP key [count]
SADD myset "one"
(integer) 1

SADD myset "two"
(integer) 1

SADD myset "three"
(integer) 1

SPOP myset
"one"

SMEMBERS myset
1) "three"
2) "two"

SADD myset "four"
(integer) 1

SADD myset "five"
(integer) 1

SPOP myset 3
1) "three"
2) "four"
3) "two"

SMEMBERS myset
1) "five"

2.1.6 SMOVE

SMOVE 命令用于将一个元素从源集合移动到目标集合。返回值:1 表示移动成功,0 表示移动失败(如元素不存在于源集合中)。

SMOVE source destination member
SADD myset "one"
(integer) 1

SADD myset "two"
(integer) 1

SADD myotherset "three"
(integer) 1

SMOVE myset myotherset "two"
(integer) 1

SMEMBERS myset
1) "one"

SMEMBERS myotherset
1) "three"
2) "two"

2.1.7 SREM

SREM 命令用于删除集合中指定的元素。返回值为成功删除的元素个数。

SREM key member [member ...]
redis> SADD myset "one"
(integer) 1

redis> SADD myset "two"
(integer) 1

redis> SADD myset "three"
(integer) 1

redis> SREM myset "one"
(integer) 1

redis> SREM myset "four"
(integer) 0

redis> SMEMBERS myset
1) "three"
2) "two"

2.1.8 集合间操作

集合间操作包括以下几种:交集(inter)、并集(union)和差集(diff)。

在这里插入图片描述

2.1.9 SINTER

SINTER 命令用于获取指定集合之间的交集元素。返回值为交集中的元素列表。

SINTER key [key ...]
SADD key1 "a"
(integer) 1

SADD key1 "b"
(integer) 1

SADD key1 "c"
(integer) 1

SADD key2 "c"
(integer) 1

SADD key2 "d"
(integer) 1

SADD key2 "e"
(integer) 1

SINTER key1 key2
1) "c"

2.1.10 SINTERSTORE

SINTERSTORE 命令用于计算指定集合的交集,并将结果保存到目标集合中。返回值为交集中元素的数量。

SINTERSTORE destination key [key ...]
redis> SADD key1 "a"
(integer) 1

redis> SADD key1 "b"
(integer) 1

redis> SADD key1 "c"
(integer) 1

redis> SADD key2 "c"
(integer) 1

redis> SADD key2 "d"
(integer) 1

redis> SADD key2 "e"
(integer) 1

redis> SINTERSTORE key key1 key2
(integer) 1

redis> SMEMBERS key
1) "c"

2.1.11 SUNION

SUNION 命令用于获取指定集合的并集元素。返回值为并集中的元素列表。

SUNION key [key ...]
redis> SADD key1 "a"
(integer) 1

redis> SADD key1 "b"
(integer) 1

redis> SADD key1 "c"
(integer) 1

redis> SADD key2 "c"
(integer) 1

redis> SADD key2 "d"
(integer) 1

redis> SADD key2 "e"
(integer) 1

redis> SUNION key1 key2
1) "a"
2) "c"
3) "e"
4) "b"
5) "d"

2.1.12 SUNIONSTORE

SUNIONSTORE 命令用于计算指定集合的并集,并将结果保存到目标集合中。返回值为并集中元素的数量。

SUNIONSTORE destination key [key ...]
redis> SADD key1 "a"
(integer) 1

redis> SADD key1 "b"
(integer) 1

redis> SADD key1 "c"
(integer) 1

redis> SADD key2 "c"
(integer) 1

redis> SADD key2 "d"
(integer) 1

redis> SADD key2 "e"
(integer) 1

redis> SUNIONSTORE key key1 key2
(integer) 5

redis> SMEMBERS key
1) "a"
2) "c"
3) "e"
4) "b"
5) "d"

2.1.13 SDIFF

SDIFF 命令用于获取指定集合之间的差集元素。返回值为差集中的元素列表。

SDIFF key [key ...]
SADD key1 "a"
(integer) 1

SADD key1 "b"
(integer) 1

SADD key1 "c"
(integer) 1

SADD key2 "c"
(integer) 1

SADD key2 "d"
(integer) 1

SADD key2 "e"
(integer) 1

SDIFF key1 key2
1) "a"
2) "b"

2.1.14 SDIFFSTORE

SDIFFSTORE 命令用于计算指定集合的差集,并将结果保存到目标集合中。返回值为差集中元素的数量。

SDIFFSTORE destination key [key ...]
SADD key1 "a"
(integer) 1

SADD key1 "b"
(integer) 1

SADD key1 "c"
(integer) 1

SADD key2 "c"
(integer) 1

SADD key2 "d"
(integer) 1

SADD key2 "e"
(integer) 1

SDIFFSTORE key key1 key2
(integer) 2

SMEMBERS key
1) "a"
2) "b"

2.1.15 命令小结

命令时间复杂度描述
sadd key element [element …]O(k),k 是元素个数向集合中添加一个或多个元素
srem key element [element …]O(k),k 是元素个数从集合中删除一个或多个元素
scard keyO(1)获取集合中元素的个数
sismember key elementO(1)判断一个元素是否在集合中
srandmember key [count]O(n),n 是 count随机返回集合中的一个或多个元素
spop key [count]O(n),n 是 count随机移除集合中的一个或多个元素
smembers keyO(k),k 是元素个数返回集合中的所有元素
sinter key [key …]O(m * k),k 是最小集合的元素个数,m 是集合个数获取多个集合的交集
sinterstore key [key …]O(m * k),k 是最小集合的元素个数,m 是集合个数计算多个集合的交集并保存到目标集合
sunion key [key …]O(k),k 是所有集合的元素总数获取多个集合的并集
sunionstore key [key …]O(k),k 是所有集合的元素总数计算多个集合的并集并保存到目标集合
sdiff key [key …]O(k),k 是所有集合的元素总数获取多个集合的差集
sdiffstore key [key …]O(k),k 是所有集合的元素总数计算多个集合的差集并保存到目标集合

2.2 内部编码

集合类型的内部编码有两种:

内部编码类型使用条件描述
intset当集合中的元素都是整数,且元素个数小于 set-max-intset-entries 配置(默认 512 个)时使用。使用紧凑的内存结构,减少内存消耗。
hashtable当集合不满足 intset 条件(如元素个数过多或包含非整数元素)时使用。使用哈希表结构,支持更高效的操作。
  1. 当元素个数较少并且都为整数时,内部编码为 intset:
sadd setkey 1 2 3 4
(integer) 4

object encoding setkey
"intset"
  1. 当元素个数超过 512 个,内部编码为 hashtable:
127.0.0.1:6379> sadd setkey 1 2 3 4
(integer) 513

127.0.0.1:6379> object encoding setkey
"hashtable"
  1. 当存在元素不是整数时,内部编码为 hashtable:
127.0.0.1:6379> sadd setkey a
(integer) 1

127.0.0.1:6379> object encoding setkey
"hashtable"

2.3 使用场景

集合类型在标签管理中有着典型的应用场景。例如,用户 A 对娱乐和体育感兴趣,用户 B 对历史和新闻感兴趣,这些兴趣点可以被抽象为标签。通过这些数据,可以找出喜欢同一标签的用户以及用户之间的共同兴趣标签,这对提升用户体验和增强用户粘性非常有帮助。例如,在电子商务网站中,可以根据不同的标签为用户推荐个性化的产品。

  1. 给用户添加标签
sadd user:1:tags tag1 tag2 tag5
sadd user:2:tags tag2 tag3 tag5
...
sadd user:k:tags tag1 tag2 tag4
  1. 给标签添加用户
sadd tag1:users user:1 user:3
sadd tag2:users user:1 user:2 user:3
...
sadd tagk:users user:1 user:4 user:9 user:28
  1. 删除用户下的标签
srem user:1:tags tag1 tag5
  1. 删除标签下的用户
srem tag1:users user:1
srem tag5:users user:1
  1. 计算用户的共同兴趣标签
sinter user:1:tags user:2:tags
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ice___Cpu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值