Redis数据类型(2)上

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容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
目录
相关文章
|
10天前
|
存储 消息中间件 NoSQL
使用Java操作Redis数据类型的详解指南
通过使用Jedis库,可以在Java中方便地操作Redis的各种数据类型。本文详细介绍了字符串、哈希、列表、集合和有序集合的基本操作及其对应的Java实现。这些示例展示了如何使用Java与Redis进行交互,为开发高效的Redis客户端应用程序提供了基础。希望本文的指南能帮助您更好地理解和使用Redis,提升应用程序的性能和可靠性。
24 1
|
30天前
|
存储 消息中间件 NoSQL
Redis 数据类型
10月更文挑战第15天
36 1
|
2月前
|
存储 消息中间件 缓存
深入探析Redis常见数据类型及应用场景
深入探析Redis常见数据类型及应用场景
54 2
|
3月前
|
NoSQL 安全 Java
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
这篇文章深入探讨了Redis中的String数据类型,包括键操作的命令、String类型的命令使用,以及String在Redis中的内部数据结构实现。
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
|
3月前
|
NoSQL Java Redis
Redis5种数据类型
这篇文章介绍了Redis的五种数据类型:字符串、列表、集合、有序集合和哈希,并通过代码示例展示了如何在Spring框架中使用RedisTemplate操作这些数据类型。
Redis5种数据类型
|
3月前
|
存储 NoSQL Java
深入理解Redis数据类型Hashes原理
本文深入分析了Redis中的hashes数据类型,这是一种用于存储行记录的数据结构,允许一个key下存储多条记录。
深入理解Redis数据类型Hashes原理
|
3月前
|
存储 NoSQL 算法
深入理解Redis数据类型Zset原理
本文深入探讨了Redis中的Zset(有序集合)数据类型,它是一种可以存储排序功能的集合,其中每个元素都具有一个浮点型的score属性,用于根据score进行排序。
深入理解Redis数据类型Zset原理
|
3月前
|
存储 NoSQL 算法
Redis6入门到实战------ 三、常用五大数据类型(列表(List)、集合(Set)、哈希(Hash)、Zset(sorted set))
这是关于Redis 6入门到实战的文章,具体内容涉及Redis的五大数据类型:列表(List)、集合(Set)、哈希(Hash)、有序集合(Zset(sorted set))。文章详细介绍了这些数据类型的特点、常用命令以及它们背后的数据结构。如果您有任何关于Redis的具体问题或需要进一步的帮助,请随时告诉我。
|
3月前
|
消息中间件 存储 NoSQL
redis实战——go-redis的使用与redis基础数据类型的使用场景(一)
本文档介绍了如何使用 Go 语言中的 `go-redis` 库操作 Redis 数据库
179 0
redis实战——go-redis的使用与redis基础数据类型的使用场景(一)
|
3月前
|
存储 缓存 NoSQL
深入理解Redis数据类型String原理
本文深入探讨了Redis中String数据类型的实现原理和使用场景,基于Redis 5.0版本进行分析。
深入理解Redis数据类型String原理