Redis-基础(数据类型和常用命令、使用场景)

本文详细介绍了Redis的基本概念、特性、安装与配置,涵盖了数据类型如String、Hash、List、Set、ZSet的应用场景和操作命令,以及分布式锁和缓存等关键功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis是什么

Redis其实是一种存取在内存中,可以持久化在硬盘中的非关系型数据库,才用KV方式存储数据。
nosql的一大代表就是redis,除此之外还有MongoDB、MemcacheDB等

Redis特性

  1. 内存中都是cpu操作,存取速度快
  2. 功能丰富,有持久化策略、过期策略等,比较完善
  3. 高可用,可搭建集群
  4. 数据类型丰富
  5. 可支持多种语言

Redis的搭建

一般来讲,我们都是在linux上面搭建redis服务端,window虽然有,但只能用作学习测试
我这边购买的服务器是阿里云轻量级应用服务器,centos7.3

前期准备工作

买好的服务器一般是一台空服务器,配好yum源,装好docker以后,就可以装redis了。
Centos7.3-yum源的更新.
centos7.3-基础环境安装.
centos7.3-数据服务安装.

客户端简单操作

[root@dasdasd /]# docker exec -it redis5 redis-cli
127.0.0.1:6379> select 6 #总共16个库,选择6号库
OK
127.0.0.1:6379[6]> set luhui 111 #set一个值
OK
127.0.0.1:6379[6]> get luhui
"111"
127.0.0.1:6379[6]> keys * #查看所有键
1) "luhui"
127.0.0.1:6379[6]> dbsize #查看键的个数
(integer) 1
127.0.0.1:6379[6]> exists luhui 查看某个键是否存在
(integer) 1
127.0.0.1:6379[6]> exists sun
(integer) 0
127.0.0.1:6379[6]> set sun 423
OK
127.0.0.1:6379[6]> del sun #删除键
(integer) 1
127.0.0.1:6379[6]> type luhui #查看键的类型
string

可视化界面操作

在这里插入图片描述
好了 有了以上步骤,后面我们就可以实际去操作学习了

Redis数据类型

分类

String、Hash、List、Set、ZSet、Hyperloglog、Geo、Streams

存储结构

redis是一个KV存储的数据库,kv是通过hashtable实现的,也就是下面的dictEntry
至于value,不管是string还是hash还是set、zset、list,本质都是一个redisObject对象
当然,下面的实现都是C语言
在这里插入图片描述

String

string是最基本最常见的,上面的例子就是操作string的,用来存储字符串、数字等

操作命令
set和get
127.0.0.1:6379[6]> set zhangsan 1
OK
127.0.0.1:6379[6]> get zhangsan
"1"
mset和mget

批量设置和批量取值,也是原子性操作

127.0.0.1:6379[6]> mset lisi 2 wangwu 3
OK
127.0.0.1:6379[6]> mget lisi wangwu
1) "2"
2) "3"
setnx和del

这两个组合可以实现分布式锁

  • setnx机制:如果键存在,则set失败,如果不存在set成功,可以用来当锁
  • del:删除键,也就是释放锁
127.0.0.1:6379[6]> setnx lisi 4
(integer) 0
127.0.0.1:6379[6]> setnx zhaoliu 4
(integer) 1
127.0.0.1:6379[6]> del zhaoliu
(integer) 1

expire key time 可以用这个命令来设置key的失效时间,也就是定时删除,避免del key失败,导致锁无法释放
setnx key value是原子性的,expire key time也是原子性的,但是他们的组合不是原子性的,所以会导致万一setnx执行成功,但是expire执行失败,锁还是无法释放。

set key value time EX = setnx+expire

setnx执行的时候,是无法同时设置失效时间的,但是set可以,
set key value [EX seconds] [PX milliseconds] [NX|XX]

  • EX seconds:设置失效时长,单位秒
  • PX milliseconds:设置失效时长,单位毫秒
  • NX:key不存在时设置value,成功返回OK,失败返回(nil)
  • XX:key存在时设置value,成功返回OK,失败返回(nil)

setnx = set key value nx

127.0.0.1:6379[6]> set lock 5 ex 20 nx
OK
# 20s之内设置,设置失败
127.0.0.1:6379[6]> set lock 10 nx
(nil)
# 20s之后设置,设置成功
127.0.0.1:6379[6]> set lock 10 nx
OK
incr/incrby,decr/decrby

自增自减,批量自增自减,也是原子性操作

127.0.0.1:6379[6]> get id
"1"
127.0.0.1:6379[6]> incr id
(integer) 2
127.0.0.1:6379[6]> decr id
(integer) 1
127.0.0.1:6379[6]> incrby id 10
(integer) 11
127.0.0.1:6379[6]> decrby id 10
(integer) 1

对于浮点数,使用incrbyfloat

其他命令
127.0.0.1:6379[6]> set name luhui
OK
# 查看长度
127.0.0.1:6379[6]> strlen name
(integer) 5
# 拼接字符
127.0.0.1:6379[6]> append name cool
(integer) 9
127.0.0.1:6379[6]> get name
"luhuicool"
# 获取指定范围的字符
127.0.0.1:6379[6]> getrange name 0 4
"luhui"
应用场景
缓存

可以存储一些热点数据,提高访问速度

分布式共享

因为redis可以独立部署,所以可以存储共享一些数据,比如session

分布式锁

上面的setnx实现的分布式锁

全局id

自增id incrby id 1

计数器

同样可以使用incrby

限流

同样还是incrby,用访问者的ip为key,访问一次加一次,超过一定次数返回false来拒绝访问

hash

当我们的value不是一个简单的字符串或者数字的时候,是一个对象的话,除了序列化这种开销比较大的方式,还有种方法就是我们的hash
也就是value,类型为上面的redisObject变成hash,不再是string

实现方式

redis本身的实现是通过hashtable实现的,这是外层的哈希。如果value的类型变成hash,那么存储value的方式叫做内层的哈希。
这个内层的哈希有两种实现方式,ziplist和hashtable,当对象较小的时候,用ziplist,较大的时候会自动进化成hashtable

这时候value对应的这个对象,它的value只能是string,不能再往下嵌套了。

操作命令

很多操作其实就是再原来string的命令前加一个h

设置一个值
127.0.0.1:6379[6]> hset luhui name "luhui" age 24
(integer) 2

在这里插入图片描述

获取这个值

要想到,现在value不是一个string了,它是一个复杂对象,所以取值方式也肯定会有变化

127.0.0.1:6379[6]> hgetall luhui
1) "name"
2) "luhui"
3) "age"
4) "24"
127.0.0.1:6379[6]> hkeys luhui
1) "name"
2) "age"
127.0.0.1:6379[6]> hvals luhui
1) "luhui"
2) "24"
修改一个字段
127.0.0.1:6379[6]> hset luhui age 25
(integer) 0
127.0.0.1:6379[6]> hgetall luhui
1) "name"
2) "luhui"
3) "age"
4) "25"

修改的时候,如果使用类似setnx的操作,如果字段存在则不做改变,返回0,如果不存在则增加

127.0.0.1:6379[6]> hsetnx luhui name "laolu"
(integer) 0
127.0.0.1:6379[6]> hgetall luhui
1) "name"
2) "luhui"
3) "age"
4) "24"
127.0.0.1:6379[6]> hsetnx luhui weight 67
(integer) 1
127.0.0.1:6379[6]> hgetall luhui
1) "name"
2) "luhui"
3) "age"
4) "24"
5) "weight"
6) "67"
增加一个字段
127.0.0.1:6379[6]> hset luhui height 178
(integer) 1
127.0.0.1:6379[6]> hgetall luhui
1) "name"
2) "luhui"
3) "age"
4) "25"
5) "height"
6) "178"
删除一个字段
127.0.0.1:6379[6]> hdel luhui height
(integer) 1
127.0.0.1:6379[6]> hgetall luhui
1) "name"
2) "luhui"
3) "age"
4) "25"
删除这个key
127.0.0.1:6379[6]> del luhui
(integer) 1
127.0.0.1:6379[6]> hgetall luhui
(empty array)

hlen是获取长度

应用场景

比起string,hash又多了一个应用场景

存储对象

比起string,hash显然更适合存储对象

list

存储结构

存储有序的字符串(从左到右),元素可以重复。可以充当队列和栈的角色
在这里插入图片描述

操作命令
设值

lpush从左边入栈,rpush从右边入栈

127.0.0.1:6379[6]> lpush queue a b c
(integer) 3
127.0.0.1:6379[6]> lrange queue 0 -1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379[6]> rpush queue d e f
(integer) 6
127.0.0.1:6379[6]> lrange queue 0 -1
1) "c"
2) "b"
3) "a"
4) "d"
5) "e"
6) "f"
弹出

元素的弹出操作

127.0.0.1:6379[6]> lpop queue
"c"
127.0.0.1:6379[6]> rpop queue
"f"
127.0.0.1:6379[6]> lrange queue 0 -1
1) "b"
2) "a"
3) "d"
4) "e"
取值

lrange key start end

  1. 第一种使用方式比较好理解,都是正数,start=0,end=3,表示从第0个到第3个元素
  2. 第二种方式不太好理解,但是使用起来方便,不用担心队列长度,start=0,end=-1,表示从第0个元素到倒数第一个元素。如果是-2,表示从第0个元素到倒数第二元素…
127.0.0.1:6379[6]> lrange queue 0 3
1) "b"
2) "a"
3) "d"
4) "e"
127.0.0.1:6379[6]> lrange queue 0 -1
1) "b"
2) "a"
3) "d"
4) "e"
127.0.0.1:6379[6]> lrange queue 0 -2
1) "b"
2) "a"
3) "d"
拓展
# 查看长度
127.0.0.1:6379[6]> llen queue
(integer) 4
127.0.0.1:6379[6]> lpush queue a a a a
(integer) 8
127.0.0.1:6379[6]> lrange queue 0 -1
1) "a"
2) "a"
3) "a"
4) "a"
5) "b"
6) "a"
7) "d"
8) "e"
# 替换索引为1处的元素
127.0.0.1:6379[6]> lset queue 1 b
OK
127.0.0.1:6379[6]> lrange queue 0 -1
1) "a"
2) "b"
3) "a"
4) "a"
5) "b"
6) "a"
7) "d"
8) "e"
# 在b后面插入c
127.0.0.1:6379[6]> linsert queue after b c
(integer) 9
127.0.0.1:6379[6]> lrange queue 0 -1
1) "a"
2) "b"
3) "c"
4) "a"
5) "a"
6) "b"
7) "a"
8) "d"
9) "e"
# 从左往右遍历,删除1个a
127.0.0.1:6379[6]> lrem queue 1 a
(integer) 1
127.0.0.1:6379[6]> lrange queue 0 -1
1) "b"
2) "c"
3) "a"
4) "a"
5) "b"
6) "a"
7) "d"
8) "e"
# 从右往左遍历,删除1个a
127.0.0.1:6379[6]> lrem queue -1 a
(integer) 1
127.0.0.1:6379[6]> lrange queue 0 -1
1) "b"
2) "c"
3) "a"
4) "a"
5) "b"
6) "d"
7) "e"
# 删除全部a元素
127.0.0.1:6379[6]> lrem queue 0 a
(integer) 2
127.0.0.1:6379[6]> lrange queue 0 -1
1) "b"
2) "c"
3) "b"
4) "d"
5) "e"
# 将链表尾部的元素弹出到头部,循环链表
127.0.0.1:6379[6]> rpoplpush queue queue
"e"
127.0.0.1:6379[6]> lrange queue 0 -1
1) "e"
2) "b"
3) "c"
4) "b"
5) "d"
应用场景

List的特点就是有序,插入删除快捷

用户消息时间线
消息队列

当然,事实上有专门的消息队列,基本不会用redis做消息队列

set

set用的比较少,命令比较少

操作命令
127.0.0.1:6379[6]> sadd myset a b c d e f
(integer) 6
127.0.0.1:6379[6]> smembers myset
1) "b"
2) "a"
3) "d"
4) "f"
5) "e"
6) "c"
# 查看元素个数
127.0.0.1:6379[6]> scard myset
(integer) 6
# 随机获取一个元素
127.0.0.1:6379[6]> srandmember myset
"c"
# 随即弹出一个元素
127.0.0.1:6379[6]> spop myset
"d"
127.0.0.1:6379[6]> smembers myset
1) "f"
2) "a"
3) "e"
4) "c"
5) "b"
# 移除某个元素
127.0.0.1:6379[6]> srem myset a
(integer) 1
127.0.0.1:6379[6]> smembers myset
1) "f"
2) "e"
3) "c"
4) "b"
# 查看元素是否存在
127.0.0.1:6379[6]> sismember myset b
(integer) 1
应用场景

set无序,对于顺序没有要求的可以用这个结构

签到、点赞、打卡等
商品标签

类似这种,某个物品的属性什么的,衣服的大小、尺码啊

zset

有序的set
在这里插入图片描述

操作

zset的几个常见的操作如下

127.0.0.1:6379[6]> zadd myzset 10 zhangsan 20 lisi 30 wangwu
(integer) 3
127.0.0.1:6379[6]> zrange myzset 0 -1 withscores
1) "zhangsan"
2) "10"
3) "lisi"
4) "20"
5) "wangwu"
6) "30"
127.0.0.1:6379[6]> zrangebyscore myzset 20 30
1) "lisi"
2) "wangwu"
127.0.0.1:6379[6]> zcard myzset
(integer) 3
127.0.0.1:6379[6]> zcount myzset 20 30
(integer) 2
127.0.0.1:6379[6]> zrank myzset lisi
(integer) 1
应用场景

排行榜等,有序的集合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

unhappy404

感谢老板打赏!!!爱您

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

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

打赏作者

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

抵扣说明:

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

余额充值