Redis常用数据结构

目录

1.Redis五大基本数据类型以及应用场景

1.1 String类型

1.2 List类型

1.3 Set类型

1.4 Hash表类型

1.5 Zset类型


1.Redis五大基本数据类型以及应用场景

1.1 String类型

String类型是redis最基本类型之一,其存储数据方式为key和value的方式,其中value即为String类型

基本操作:

# 设置一个键值对 键为k1,值为v2
127.0.0.1:6379> set k1 v1
OK
 
# 设置一个键值对 键为k2,值为k2
127.0.0.1:6379> set k2 v2
OK
 
# 根据键,获取值
127.0.0.1:6379> get k1
"v1"
 
# 给字符串最加值
127.0.0.1:6379> append k1 "222"
(integer) 5
127.0.0.1:6379> get k1
"v1222"
 
# 修改字符换
127.0.0.1:6379> set k1 v2new
OK
127.0.0.1:6379> get k1
"v2new"
127.0.0.1:6379> set number 1
OK
 
# 特殊命令, 可以给整形字符串自增自减操作
127.0.0.1:6379> incr number
(integer) 2
127.0.0.1:6379> get number
"2"
127.0.0.1:6379> decr number
(integer) 1
127.0.0.1:6379> get number
"1"
 
# 范围获取字符串
127.0.0.1:6379> set k3 aaabbbcccddd
127.0.0.1:6379> getrange k3 0 5
"aaabbb"
 
# 从指定位置更新字符串
127.0.0.1:6379> setrange k3 5 zzzzzz
(integer) 12
127.0.0.1:6379> get k3
"aaabbzzzzzzd"

redis还支持给数据添加过期时间,如:

# 给某个字符串值设置过期时间,比如,给k4 = v4这组值的v4设置过期时间为10秒
127.0.0.1:6379> setex k4 10 v4
OK
# 10 秒内还可以正常获取
127.0.0.1:6379> get k4
"v4"
# ttl可以查看某一个键的过期时间
127.0.0.1:6379> ttl k4
(integer) 3
# 负数代表已经过去
127.0.0.1:6379> ttl k4
(integer) -2
# 再次获取已无法获取
127.0.0.1:6379> get k4
(nil)

有时候我们需要值不存在的情况下才进行设置,这个时候就需要setnx(set if not exist)命令,如:

# 设置键值对 k5 v5
127.0.0.1:6379> setnx k5 v5
(integer) 1
# 再次设置,数据已存在,失败
127.0.0.1:6379> setnx k5 v5
(integer) 0

批量操作,这里我们先清空数据库

# 清空数据库
127.0.0.1:6379> flushdb
OK
# 查看存在的所有键值
127.0.0.1:6379> keys *
(empty list or set)

批量添加和批量获取

# 批量字符串类型
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
# 查看所有的键
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
# 批量获取
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"

当然,当我们要存储的是一个对象,而不是单单一个值时,我们用string类型存储时,可以参考以下方法,比如,我们需要创建一个user对象,该对象有id,name,age三个字段,如两个user对象:

user{
        id = 1
        name = zhangsan
        age = 15
    }
user{
        id = 2
        name = lisi
        age = 25
    }

那么采用string类型,可以参考以下方法存储在redis中

127.0.0.1:6379> set user:1:name zhangsan
OK
127.0.0.1:6379> set user:1:age 15
OK
127.0.0.1:6379> set user:2:name lisi
OK
127.0.0.1:6379> set user:2:age 25
OK
127.0.0.1:6379> keys *
1) "user:2:age"
2) "user:2:name"
3) "user:1:age"
4) "user:1:name"
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "15"
127.0.0.1:6379> mget user:2:name user:2:age
1) "lisi"
2) "25"

应用场景:

(1) 存储一些简单数据

(2) 对象缓存


1.2 List类型

list是一种数据结构(链表),可以将list当成栈,也可以当成队列,如:

基本操作

# 往链表左端添加元素
127.0.0.1:6379> lpush list a
(integer) 1
127.0.0.1:6379> lpush list b
(integer) 2
127.0.0.1:6379> lpush list c
(integer) 3
# 往链表右端添加元素
127.0.0.1:6379> rpush list a
(integer) 4
127.0.0.1:6379> rpush list b
(integer) 5
127.0.0.1:6379> rpush list c
(integer) 6
# 查看整张链表的数据
127.0.0.1:6379> lrange list 0 -1
1) "c"
2) "b"
3) "a"
4) "a"
5) "b"
6) "c"
# 查看部分数据,提供范围即可
127.0.0.1:6379> lrange list 0 2
1) "c"
2) "b"
3) "a"
# 左边弹出一个元素
127.0.0.1:6379> lpop list
"c"
# 右边弹出一个元素
127.0.0.1:6379> rpop list
"c"
# 查看结果
127.0.0.1:6379> lrange list 0 -1
1) "b"
2) "a"
3) "a"
4) "b"
# 移除一个指定元素(可以指定要删除的指定元素的个数,链表允许有重复元素)
# 删除一个a
127.0.0.1:6379> lrem list 1 a
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "b"
2) "a"
3) "b"
# 删除两个b
127.0.0.1:6379> lrem list 2 b
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "a"
# 获取指定位置的元素
127.0.0.1:6379> lindex list 0
"a"

截取链表

# 创建链表d c b a
127.0.0.1:6379> lpush list2 a
(integer) 1
127.0.0.1:6379> lpush list2 b
(integer) 2
127.0.0.1:6379> lpush list2 c
(integer) 3
127.0.0.1:6379> lpush list2 d
(integer) 4
# 截取链表的一部分
# 截取链表指定范围的元素
127.0.0.1:6379> ltrim list2 1 2
OK
# 结果
127.0.0.1:6379> lrange list2 0 -1
1) "c"
2) "b"

一些特殊操作

# 创建链表d c b a
127.0.0.1:6379> lpush list3 a
(integer) 1
127.0.0.1:6379> lpush list3 b
(integer) 2
127.0.0.1:6379> lpush list3 c
(integer) 3
127.0.0.1:6379> lpush list3 d
(integer) 4
# 从原列表的右边弹出一个元素,并添加在另外一个列表的左边
127.0.0.1:6379> rpoplpush list3 list4
"a"
127.0.0.1:6379> lrange list3 0 -1
1) "d"
2) "c"
3) "b"
127.0.0.1:6379> lrange list4 0 -1
1) "a"

应用场景:

(1)用作栈

(2)用作队列(如消息队列)

总结:list实际上是一个列表,left right都可以插入值(也可以在中间插入值,但是效率较低)


1.3 Set类型

set类型的数据类型与List数据类型对最大的不同就是不允许存在相同的元素(无序,不重复集合)

基本操作

# 添加元素
127.0.0.1:6379> sadd set1 a
(integer) 1
127.0.0.1:6379> sadd set1 b
(integer) 1
127.0.0.1:6379> sadd set1 c
(integer) 1
# 添加重复元素,操作失败
127.0.0.1:6379> sadd set1 a
(integer) 0
# 获取set集合中的所有元素
127.0.0.1:6379> smembers set1
1) "c"
2) "b"
3) "a"
# 获取set集合中的元素个数
127.0.0.1:6379> scard set1
(integer) 3
# 删除指定元素
127.0.0.1:6379> srem set1 a
(integer) 1
127.0.0.1:6379> smembers set1
1) "c"
2) "b"

set集合的一些高级操作(差交并集)

# 创建set2
127.0.0.1:6379> sadd set2 a
(integer) 1
127.0.0.1:6379> sadd set2 b
(integer) 1
127.0.0.1:6379> sadd set2 c
(integer) 1
# 创建set3
127.0.0.1:6379> sadd set3 b
(integer) 1
127.0.0.1:6379> sadd set3 c
(integer) 1
127.0.0.1:6379>
# 求set2和set3的差集
127.0.0.1:6379> sdiff set2 set3
1) "a"
# 求set2和set3的交集
127.0.0.1:6379> sinter set2 set3
1) "c"
2) "b"
# 求set2和set3的并集
127.0.0.1:6379> sunion set2 set3
1) "a"
2) "b"
3) "c"
4) "d"

应用场景:

(1) 数据不能重复的场景

(2) 共同关注,共同好友,可能认识的人(交集)


1.4 Hash表类型

Hash表类型可以理解成一个Map集合,即Value是一个Map集合

基本操作:

# 给map1添加一个元素
127.0.0.1:6379> hset map1 name zhangsan
(integer) 1
# 批量添加
127.0.0.1:6379> hmset map1 age 15 gender male
OK
127.0.0.1:6379> hkeys mao1
(empty list or set)
127.0.0.1:6379> hkeys map1
1) "name"
2) "age"
3) "gender"
# 判断是否存在某个键
127.0.0.1:6379> hexists map1 name
(integer) 1
127.0.0.1:6379> hexists map1 id
(integer) 0
# 查看当前hash表的所有键
127.0.0.1:6379> hkeys map1
1) "name"
2) "age"
3) "gender"
# 查看当前hash表的所有值
127.0.0.1:6379> hvals map1
1) "zhangsan"
2) "15"
3) "male"
# 获取指定元素
127.0.0.1:6379> hget map1 name
"zhangsan"
# 获取所有元素
127.0.0.1:6379> hgetall map1
1) "name"
2) "zhangsan"
3) "age"
4) "15"
5) "gender"
6) "male"
# 修改元素
127.0.0.1:6379> hset map1 name lisi
(integer) 0
127.0.0.1:6379> hget map1 name
"lisi"
# 删除元素
127.0.0.1:6379> hdel map1 name
(integer) 1
127.0.0.1:6379> hget map1 name
(nil)
# 获取哈希表长度
127.0.0.1:6379> hlen map1
(integer) 2

使用hash存储对象,还是以user对象为例

user{
        id = 1
        name = zhangsan
        age = 15
    }
user{
        id = 2
        name = lisi
        age = 25
    }
127.0.0.1:6379> hmset user:1 name zhangsan age 15
OK
127.0.0.1:6379> hmset user:2 name lisi age 25
OK
127.0.0.1:6379> hgetall user:1
1) "name"
2) "zhangsan"
3) "age"
4) "15"
127.0.0.1:6379> hgetall user:2
1) "name"
2) "lisi"
3) "age"
4) "25"

可以看到,采用hash表结构更适合存储对象

应用场景:

(1) 存储对象

(2) 统计数据


1.5 Zset类型

在set的基础上增加了一个值(这个值可以用来排序),可以把Zset看成是有序set

# 创建Zset集合,给每个元素添加一个score
127.0.0.1:6379> zadd zset1 1 zhangsan
(integer) 1
127.0.0.1:6379> zadd zset1 2 lisi
(integer) 1
127.0.0.1:6379> zadd zset1 3 wangwu 4 liuer
(integer) 2
# 范围获取元素,-inf +inf 代表整个范围(升序)
127.0.0.1:6379> zrangebyscore zset1 -inf +inf
1) "zhangsan"
2) "lisi"
3) "wangwu"
4) "liuer"
# 范围获取元素,-inf +inf 代表整个范围(降序)
127.0.0.1:6379> zrevrange zset1 0 -1 withscores
1) "liuer"
2) "4"
3) "wangwu"
4) "3"
5) "lisi"
6) "2"
7) "zhangsan"
8) "1"
# 带上score
127.0.0.1:6379> zrangebyscore zset1 -inf +inf withscores
1) "zhangsan"
2) "1"
3) "lisi"
4) "2"
5) "wangwu"
6) "3"
7) "liuer"
8) "4"
# 删除指定元素
127.0.0.1:6379> zrem zset1 liuer
(integer) 1
# 查看所有元素
127.0.0.1:6379> zrange zset1 0 -1
1) "zhangsan"
2) "lisi"
3) "wangwu"

其他操作和set类似(支持范围查询等等),这里不再一一展示。

应用场景:

(1) 排序(排行榜(比如用浏览量,热度为score进行排序),工资表排序等等)

(2) 消息重要程度(score作为权重)

本文参考: Redis常用数据结构_旋转的冬瓜皮的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值