Redis数据类型(2)上

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis数据类型(2)上

作者简介:码上言



代表教程:Spring Boot + vue-element 开发个人博客项目实战教程



专栏内容:个人博客系统



我的文档网站:http://xyhwh-nav.cn/

文章目录

Redis数据类型

Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样。

这里先列出五中数据类型:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Zset(有序集合)需要注意的是:


每种数据结构都有自己底层的内部编码实现,而且是多种实现,这样Redis会在合适的场景选择合 适的内部编码。

每种数据结构都有两种以上的内部编码实现,例如string数据结构就包含了raw、int和 embstr三种内部编码。

有些内部编码可以作为多种外部数据结构的内部实现,例如ziplist就是hash、list和zset共有的内部编码

1、Redis 键(key)

Redis 键命令用于管理 redis 的键。

例如:我们删除key,前提是key存在。

127.0.0.1:6379> set name redis
OK
127.0.0.1:6379> del name
(integer) 1

DEL 是一个命令, runoobkey 是一个键。 如果键被删除成功,命令执行后输出 (integer) 1,否则将输出 (integer) 0

接下来我们来学习key的有关命令。

通过help [command] 可以查看一个命令的具体用法:

127.0.0.1:6379> help keys
KEYS pattern
summary: Find all keys matching the given pattern
since: 1.0.0
group: generic

1.1、KEYS pattern

查看所有符合给定模式的key

127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set name redis
OK
127.0.0.1:6379> keys *
1) "name"

1.2、EXISTS key

检查给定 key 是否存在。

127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> exists age
(integer) 0

1.3、DEL key

该命令用于在 key 存在时删除 key。

127.0.0.1:6379> DEL name
(integer) 1
127.0.0.1:6379> DEL age
(integer) 0

1.4、MOVE key db

将当前数据库的 key 移动到给定的数据库 db 当中。

127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> keys *
(empty list or set)
//切换到数据库1中,查询
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "name"

1.5、EXPIRE key seconds

为给定 key 设置过期时间,以秒计

127.0.0.1:6379> expire name 3
(integer) 1
//等3秒查询
127.0.0.1:6379> keys *
(empty list or set)

1.6、RENAME key newkey

修改key的名称

127.0.0.1:6379> rename name name1
OK
127.0.0.1:6379> keys *
1) "name1"

1.7、TYPE key

返回 key 所储存的值的类型。

127.0.0.1:6379> type name
string

1.8、PERSIST key

移除 key 的过期时间,key 将持久保持。

127.0.0.1:6379> set age 12
OK
127.0.0.1:6379> expire age 60
(integer) 1
127.0.0.1:6379> persist age
(integer) 1
127.0.0.1:6379> ttl age
(integer) -1

1.9、TTL key

查看还有多少秒过期,-1 表示永不过期,-2 表示已过期。

以下是设置age为10秒过期,中间使用ttl查看还有多久过期,最后过期就会返回-2

127.0.0.1:6379> expire age 10
(integer) 1
127.0.0.1:6379> ttl age
(integer) 5
127.0.0.1:6379> ttl age
(integer) 1
127.0.0.1:6379> ttl age
(integer) -2

2、 字符串(String)

String是redis最基本的类型,你可以理解成Memcached一模一样的类型,一个key对应一个value

Redis的string可以包含任何数据,比如jpg图片或者序列化的对象。
其value是字符串,不过根据字符串的格式不同,又可以分为3类:

  • string:普通字符串
  • int:整数类型,可以做自增、自减操作
  • float:浮点类型,可以做自增、自减操作

不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型的最大空间不能超过512M

2.1、SET key value

设置指定 key 的值。

127.0.0.1:6379> set name xiaoming
OK

2.2、GET key

获取指定 key 的值。

127.0.0.1:6379> get name
"xiaoming"

2.3、MSET key value [key value …]

批量添加多个String类型的键值对

127.0.0.1:6379> mset k1 v1 k2 v2
OK
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
3) "name"

2.4、MGET key1 [key2…]

根据多个key获取多个String类型的value,这个可以用在项目的浏览量和点赞的应用上

127.0.0.1:6379> mget k1 k2
1) "v1"
2) "v2"

2.5、INCR key

将 key 中储存的数字值增一。

127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> incr age
(integer) 21
127.0.0.1:6379> incr age
(integer) 22

2.6、INCRBY key increment

让一个整型的key自增并指定步长,例如:incrby num 2 让num值自增2

127.0.0.1:6379> incr age
(integer) 22
127.0.0.1:6379> incrby age 20
(integer) 42

2.7、INCRBYFLOAT key increment

将 key 所储存的值加上给定的浮点增量值(increment)

127.0.0.1:6379> incrbyfloat age 9
"51"
127.0.0.1:6379> incrbyfloat age 0.1
"51.10000000000000001"

2.8、DECR key

将 key 中储存的数字值减一。

127.0.0.1:6379> set num 1
OK
127.0.0.1:6379> decr num
(integer) 0

2.9、DECRBY key decrement

key 所储存的值减去给定的减量值(decrement) 。

127.0.0.1:6379> incrby num 20
(integer) 21
127.0.0.1:6379> decrby num 10
(integer) 11

2.10、SETNX key value

添加一个String类型的键值对,前提是这个key不存在,否则不执行

127.0.0.1:6379> setnx num 10
(integer) 0
127.0.0.1:6379> get num
"11"

2.11、SETEX key seconds value

添加一个String类型的键值对,并且指定有效期(以秒为单位)。

127.0.0.1:6379> setex time 200 fly
OK
127.0.0.1:6379> get time
"fly"

2.12、APPEND key value

如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾

127.0.0.1:6379> get num
"11"
127.0.0.1:6379> append num 200
(integer) 5
127.0.0.1:6379> get num
"11200"

2.13、GETRANGE key start end

getrange 获取指定区间范围内的值,类似between…and的关系,从零到负一表示全部

127.0.0.1:6379> set name a3121assaxd
OK
//全部获取
127.0.0.1:6379> getrange name 0 -1
"a3121assaxd"
//截取部分字符串
127.0.0.1:6379> getrange name 0 2
"a31"

2.14、SETRANGE key offset value

setrange 设置指定区间范围内的值,格式是setrange key值 具体值

127.0.0.1:6379> setrange name 1 xxx
(integer) 11
127.0.0.1:6379> get name
"axxx1assaxd"

2.15、总结

  • String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字。
  • 常规key-value缓存应用: 常规计数:微博数,粉丝数等。
    问题1:Redis没有类似MySQL中的Table的概念,我们该如何区分不同类型的key呢?

比如在我们开发一个项目中,需要将用户和产品的信息存入到id,这时用户的id和产品的id可能都为1,那我们怎么存储到redis,我们知道redis的key不能重复。
这时我们就要看一下key的结构了:

Redis的key允许有多个单词形成层级结构,多个单词之间用’:'隔开,格式如下:
例如:项目名称:业务名称:类型:id

这个格式并非固定,也可以根据自己的需求来删除或添加词条。

例如我们的项目名称叫 blog,有user和product两种不同类型的数据,我们可以这样定义key:user相关的key:blog:user:1

product相关的key:blog:product:1

如果Value是一个Java对象,例如一个User对象,则可以将对象序列化为JSON字符串后存储:

key value
blog:user:1 {“id”:1, “name”: “xiaoming”, “phone”: 123456789}
blog:product:1 {“id”:1, “name”: “huwei”, “color”: “red”}

添加的数据:

'{"id":1, "name":"xiaoming", "phone": 12345678911}'
'{"id":2, "name":"xiaohong", "phone": 18212121111}'
'{"id":1, "name":"huwei", "color": "red"}'
'{"id":2, "name":"xiaomi", "color": "black"}'
127.0.0.1:6379> set blog:user:1 '{"id":1, "name": "xiaoming", "phone": 123456789}'
OK
127.0.0.1:6379> set blog:user:2 '{"id":2, "name":"xiaohong", "phone": 18212121111}'
OK
127.0.0.1:6379> set blog:product:1 '{"id":1, "name":"huwei", "color": "red"}'
OK
127.0.0.1:6379> set blog:product:2 '{"id":2, "name":"xiaomi", "color": "black"}'
OK

添加完之后,打开之前安装的Redis客户端工具,然后查看我们刚添加的数据,树状的文件夹列表。还有很多的命令这里不再一一讲述,具体可以看官网发布的命令去学习:https://redis.io/commands

3、哈希(Hash)

Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。如用户信息等。

Redis hash 是一个键值对集合,类似于Java中的HashMap结构。
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。

String结构是将对象序列化为JSON字符串后存储,当需要修改对象某个字段时很不方便

key value
blog:user:1 {“id”:1, “name”: “xiaoming”, “phone”: 123456789}
blog:user:2 {“id”:2, “name”:“xiaohong”, “phone”: 18212121111}

Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD:
以下是Hash常见的命令:

3.1、HSET key field value

添加或者修改hash类型 key 的field的值

127.0.0.1:6379> hset dog color red
(integer) 1
127.0.0.1:6379> hset dog age 2
(integer) 1
127.0.0.1:6379> hset tree name guihua
(integer) 1
127.0.0.1:6379> hset tree age 20
(integer) 1

3.2、HGET key field

获取存储在哈希表中指定字段的值。

127.0.0.1:6379> hget tree age
"20"
127.0.0.1:6379> hget dog color
"red"

3.3、HMSET key field1 value1 [field2 value2 ]

批量添加多个hash类型key的field的值

127.0.0.1:6379> hmset dog name xiaohua sex nan
OK

3.4、HMGET key field1 [field2]

批量获取多个hash类型key的field的值

127.0.0.1:6379> hmget dog name age
1) "xiaohua"
2) "2"

3.5、HGETALL key

获取在哈希表中指定 key 的所有字段和值

127.0.0.1:6379> hgetall dog
1) "color"
2) "red"
3) "age"
4) "2"
5) "name"
6) "xiaohua"
7) "sex"
8) "nan"

3.6、HKEYS key

获取一个hash类型的key中的所有的field

127.0.0.1:6379> hkeys dog
1) "color"
2) "age"
3) "name"
4) "sex"

3.7、HVALS key

获取一个hash类型的key中的所有的value

127.0.0.1:6379> hvals dog
1) "red"
2) "2"
3) "xiaohua"
4) "nan"

3.8、HINCRBY key field increment

让一个hash类型key的字段值自增并指定步长

127.0.0.1:6379> hincrby dog age 5
(integer) 7

3.9、HSETNX key field value

只有在字段 field 不存在时,设置哈希表字段的值。

127.0.0.1:6379> hsetnx dog age 3
(integer) 0

3.10、HEXISTS key field

查看哈希表 key 中,指定的字段是否存在。

127.0.0.1:6379> hexists dog name
(integer) 1

3.11、HLEN key

获取哈希表中字段的数量

127.0.0.1:6379> hlen dog
(integer) 4

4、列表(List)

Redis列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

它的底层实际是个链表 !
Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。

特征也与LinkedList类似:

  • 有序
  • 元素可以重复
  • 插入和删除快
  • 查询速度一般

  • 常用来存储一个有序数据,例如:朋友圈点赞列表,评论列表等。

一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

4.1、LPUSH key value1 [value2]

将一个或多个值插入到列表头部(左侧)。

127.0.0.1:6379> lpush cat xiaohua
(integer) 1

4.2、LPOP key

移出并获取列表的第一个元素(左侧),当列表 key 不存在时,则返回nil。

127.0.0.1:6379> lpop cat1
(nil)
127.0.0.1:6379> lpop cat
"xiaohua"

4.3、RPUSH key value1 [value2]

向列表右侧插入一个或多个元素。

127.0.0.1:6379> rpush cat xiaolan xiaoming
(integer) 2

4.4、RPOP key

移除并返回列表右侧的第一个元素。

127.0.0.1:6379> rpop cat
"xiaoming"

4.5、LRANGE key start stop

获取列表指定范围内的元素。

其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推

0,-1范围是全部查出。

127.0.0.1:6379> lrange cat 0 2
1) "xiaolan"

4.6、LREM key count value

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

127.0.0.1:6379> lrem cat 1 "xiaolan"
(integer) 1

4.7、LTRIM key start stop

对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。

127.0.0.1:6379> RPUSH mylist "hello"
(integer) 1
127.0.0.1:6379> RPUSH mylist "hello"
(integer) 2
127.0.0.1:6379> RPUSH mylist "foo"
(integer) 3
127.0.0.1:6379> RPUSH mylist "bar"
(integer) 4
127.0.0.1:6379>  LTRIM mylist 1 -1
OK
127.0.0.1:6379>  LRANGE mylist 0 -1
1) "hello"
2) "foo"
3) "bar"

4.8、RPOPLPUSH source destination

移除列表的最后一个元素,并将该元素添加到另一个列表并返回

127.0.0.1:6379> rpoplpush mylist myotherlist
"bar"
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "foo"

4.9、LSET key index value

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

127.0.0.1:6379> exists mylist    # 对空列表(key 不存在)进行 LSET
(integer) 1
127.0.0.1:6379> lset mylist 0 item  # 对非空列表进行 LSET
OK
127.0.0.1:6379> LRANGE mylist 0 -1
1) "item"
2) "foo"

4.10、LINSERT key BEFORE|AFTER pivot value

在列表的元素前或者后插入元素。

127.0.0.1:6379> LINSERT mylist BEFORE "foo" "world"
(integer) 3
127.0.0.1:6379> Lrange mylist 0 -1
1) "item"
2) "world"
3) "foo"

4.11、LLEN key

获取哈希表中字段的数量。

127.0.0.1:6379> Llen mylist
(integer) 3

4.12、Lindex key index

按照索引下标获得元素(-1代表最后一个,0代表是第一个,即所有)

相当于 Java 链表操作中的 get(int index) 操 作;

127.0.0.1:6379> Lindex cat 1
(nil)
127.0.0.1:6379> Lindex cat 0
"xiaolan"
127.0.0.1:6379> Lindex cat -1
"xiaolan"

4.13、总结

  • 链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就低了。
  • 它是一个字符串链表,left,right 都可以插入添加 。
  • 如果键不存在,创建新的链表 如果键已存在,新增内容。
  • 如果值全移除,对应的键也就消失了。

    list就是链表,略有数据结构知识的人都应该能理解其结构。使用Lists结构,我们可以轻松地实现最新消息排行等功能。List的另一个应用就是消息队列,可以利用List的PUSH操作,将任务存在List中,然后工作线程再用POP操作将任务取出进行执行。Redis还提供了操作List中某一段的api,你可以直接查询,删除List中某一段的元素。


Redis的list是每个子元素都是String类型的双向链表,可以通过push和pop操作从列表的头部或者尾部 添加或者删除元素,这样List即可以作为栈,也可以作为队列。

4.14、问题

1、list 实现队列

队列是先进先出的数据结构,常用于消息排队和异步逻辑处理,它会确保元素的访问顺序:

127.0.0.1:6379> RPUSH books python java golang
(integer) 3
127.0.0.1:6379> LPOP books
"python"
127.0.0.1:6379> LPOP books
"java"
127.0.0.1:6379> LPOP books
"golang"
127.0.0.1:6379> LPOP books
(nil)

2、list 实现栈

栈是先进后出的数据结构,跟队列正好相反:

127.0.0.1:6379> RPUSH books python java golang
(integer) 3
127.0.0.1:6379> RPOP books
"golang"
127.0.0.1:6379> RPOP books
"java"
127.0.0.1:6379> RPOP books
"python"
127.0.0.1:6379> RPOP books
(nil)
127.0.0.1:6379>


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
16小时前
|
存储 消息中间件 NoSQL
Redis数据类型详解:选择合适的数据结构优化你的应用
Redis数据类型详解:选择合适的数据结构优化你的应用
|
17小时前
|
存储 NoSQL 算法
Redis的三种特殊数据类型
【1月更文挑战第6天】Redis的三种特殊数据类型
37 1
|
16小时前
|
SQL NoSQL Java
Redis数据类型 Hash Set Zset Bitmap HyperLogLog GEO
Redis数据类型 Hash Set Zset Bitmap HyperLogLog GEO
17 0
|
16小时前
|
存储 NoSQL 定位技术
Redis常用数据类型及常用命令
这些是Redis中常用的数据类型和命令。Redis还提供了许多其他命令和功能,用于数据存储、操作和查询。你可以根据需要选择适当的数据类型和命令来满足你的应用程序需求。
24 4
|
17小时前
|
SQL NoSQL 定位技术
Redis基本命令和常用数据类型
Redis基本命令和常用数据类型
139 0
|
16小时前
|
存储 SQL NoSQL
Redis入门到通关之五大基本数据类型及其使用场景
Redis入门到通关之五大基本数据类型及其使用场景
17 0
|
16小时前
|
存储 NoSQL Redis
第十八章 Redis查看配置文件和数据类型
第十八章 Redis查看配置文件和数据类型
20 0
|
16小时前
|
存储 SQL NoSQL
Redis的数据类型
Redis的数据类型
20 0
|
16小时前
|
存储 XML NoSQL
Redis支持哪些数据类型?
Redis提供五种数据类型:String(支持JSON、XML等序列化,最大512MB),Hash(键值对,适合存储对象),List(有序列表,可在两端添加元素),Set(无序唯一元素集合),以及Sorted Set(有序集合,元素带分数排序)。每种类型有特定应用场景,优化了数据操作效率。
13 0
|
16小时前
|
存储 消息中间件 NoSQL
Redis 常见数据类型(对象类型)和应用案列
接下来,让我们走进 Redis 的对象世界,Redis 5.0版本就已经支持了下面的 9 种类型,分别是 :字符串对象、列表对象、哈希对象、集合对象、有序集合对象、Bitmaps 对象、HyperLogLog 对象、Geospatial 对象、Stream对象。
Redis 常见数据类型(对象类型)和应用案列