【赵渝强老师】Redis中的字符串

Redis的优势之一在于提供了丰富的数据类型,它不仅仅支持基本的Key-Value类型数据,还提供list、set、zset和hash等数据结构的存储。Redis没有直接使用C语言传统的字符串表示方式,而是自己构建了一种名为简单动态字符串的抽象类型,并将该类型用作Redis的默认字符串表示。简单动态字符串的英文是Simple Dynamic String,缩写为SDS。

视频讲解如下
【赵渝强老师】Redis中的字符串

Redis使用SDS表示字符串的优势在于:

  • 获取字符串的长度的事件复杂度为o(1)。
  • API安全,即通过API操作sds不会造成缓冲区溢出。
  • 每次修改字符串不一定需要进行内存分配,提高性能。
  • 可以保存文本和二进制数据。

SDS字符串的结构声明如下:

c 复制代码
struct sdshdr {
    // 记录 buf 数组中已经使用字节的数量
    // 等于 SDS 所保存字符串的长度
    unsigned int len;
    // 记录 buf 数组中还未使用字节的数量
    unsigned int free;
    // 字节数组,数据域,保存字符数据
    char buf[];
};

SDS字符串结构中的buf是一个柔性数组(Flexible Array Member),又称伸缩性数组成员,这种数组主要是为了结构体而产生的。因为开发时,偶尔需要在结构体中存放长度可变的数组,一般情况下会定义一个数组指针,在需要时分配内存使用,这样有个缺点就是,内存利用的效率很低,所以柔性数组作用就像动态数组一样,可以在结构体中存放一个长度动态的字符串。下图展示了一个使用SDS存储的字符串。

下面是在Redis中如何操作字符串。

  • SET key value
    设置指定key的值
powershell 复制代码
# 对不存在的键进行设置
redis 127.0.0.1:6379> SET key "value"
OK

redis 127.0.0.1:6379> GET key
"value"

# 对已存在的键进行设置
redis 127.0.0.1:6379> SET key "new-value"
OK

redis 127.0.0.1:6379> GET key
"new-value"
  • GET key
    获取指定key的值
powershell 复制代码
# 对不存在的 key 或字符串类型 key 进行 GET
redis> GET db
(nil)

redis> SET db redis
OK

redis> GET db
"redis"

# 对不是字符串类型的 key 进行 GET
redis> DEL db
(integer) 1

redis> LPUSH db redis mongodb mysql
(integer) 3

redis> GET db
(error) ERR Operation against a key holding the wrong kind of value
  • GETRANGE key start end
    返回 key 中字符串值的子字符
powershell 复制代码
redis> SET mykey "This is my test key"
OK

redis> GETRANGE mykey 0 3
"This"

redis> GETRANGE mykey 0 -1
"This is my test key"
  • GETSET key value
    将给定key的值设为value ,并返回key的旧值(old value)
powershell 复制代码
redis> DEL db
(integer) 1

redis> GETSET db mongodb    # 没有旧值,返回 nil
(nil)

redis> GET db
"mongodb"

redis> GETSET db redis      # 返回旧值 mongodb
"mongodb"

redis> GET db
"redis"
  • MGET key1 [key2...]
    获取所有(一个或多个)给定key的值
powershell 复制代码
redis> SET key1 "hello"
OK

redis> SET key2 "world"
OK

redis> MGET key1 key2 someOtherKey
1) "Hello"
2) "World"
3) (nil)
  • SETEX key seconds value
    将值value关联到key ,并将key的过期时间设为seconds(以秒为单位)
powershell 复制代码
redis> SETEX mykey 10 redis
OK

redis> TTL mykey
10

redis> GET mykey
"redis
  • SETNX key value
    只有在key不存在时设置 key 的值
powershell 复制代码
redis> EXISTS job                # job 不存在
(integer) 0

redis> SETNX job "programmer"    # job 设置成功
(integer) 1

redis> SETNX job "code-farmer"   # 尝试覆盖 job ,失败
(integer) 0

redis> GET job                   # 没有被覆盖
"programmer"
  • SETRANGE key offset value
    用value参数覆写给定key所储存的字符串值,从偏移量offset开始
powershell 复制代码
redis> SET key1 "Hello World"
OK

redis> SETRANGE key1 6 "Redis"
(integer) 11

redis> GET key1
"Hello Redis"
  • STRLEN key
    返回key所储存的字符串值的长度
powershell 复制代码
# 获取字符串的长度
redis> SET mykey "Hello world"
OK

redis> STRLEN mykey
(integer) 11

# 不存在的 key 长度为 0
redis> STRLEN nonexisting
(integer) 0
  • MSET key value [key value ...]
    同时设置一个或多个key-value对
powershell 复制代码
redis> MSET key1 "Hello" key2 "World"
OK

redis> GET key1
"Hello"

redis> GET key2
1) "World"
  • MSETNX key value [key value ...]
    同时设置一个或多个key-value对,当且仅当所有给定key都不存在
powershell 复制代码
# 对不存在的 key 进行 MSETNX
redis> MSETNX rmdbs "MySQL" nosql "MongoDB" key-value-store "redis"
(integer) 1

redis> MGET rmdbs nosql key-value-store
1) "MySQL"
2) "MongoDB"
3) "redis"

# MSET 的给定 key 当中有已存在的 key
redis> MSETNX rmdbs "Sqlite" language "python"  
(integer) 0               # rmdbs键已经存在,操作失败

redis> EXISTS language    # 因为MSET是原子性操作,language没有被设置
(integer) 0

redis> GET rmdbs          # rmdbs也没有被修改
"MySQL"
  • PSETEX key milliseconds value
    这个命令和SETEX命令相似,但它以毫秒为单位设置key的生存时间,而不是像SETEX命令那样,以秒为单位
powershell 复制代码
redis> PSETEX mykey 1000 "Hello"
OK

redis> PTTL mykey
999

redis> GET mykey
1) "Hello"
  • APPEND key value
    如果key已经存在并且是一个字符串,APPEND命令将指定的value追加到该key原来值(value)的末尾
powershell 复制代码
# 对不存在的 key 执行 APPEND
redis> EXISTS myphone            # 确保myphone不存在
(integer) 0

redis> APPEND myphone "nokia"    # 对不存在的key进行APPEND等同于SET myphone "nokia"
(integer) 5                      # 字符长度

# 对已存在的字符串进行 APPEND
redis> APPEND myphone " - 1110"  # 长度从5个字符增加到12个字符
(integer) 12

redis> GET myphone
"nokia - 1110"
相关推荐
2401_8654396314 分钟前
CSS如何实现图片自动裁剪填充_巧用object-fit属性控制尺寸
jvm·数据库·python
m0_7488394918 分钟前
HTML函数能否用液态金属散热提升性能_极端散热方案实测【汇总】
jvm·数据库·python
2301_8035389519 分钟前
mysql添加索引导致插入变慢怎么办_索引优化与异步处理方案
jvm·数据库·python
2301_7826591820 分钟前
如何防止SQL脏数据写入_利用触发器实现强一致性校验
jvm·数据库·python
我叫黑大帅21 分钟前
Go 项目中 Redis 缓存的实用设计与实现(Cache-Aside 模式)
redis·后端·面试
2301_8176722623 分钟前
如何实现元素从底部进入视口时触发 sticky 定位
jvm·数据库·python
InfinteJustice29 分钟前
mysql如何排查插件加载失败原因_mysql plugin目录与权限核对
jvm·数据库·python
qq_1898070331 分钟前
Go语言怎么连接Elasticsearch_Go语言Elasticsearch教程【收藏】
jvm·数据库·python
迷藏49439 分钟前
**TiDB 在高并发场景下的性能优化实战:从慢查询到极致吞吐的跃迁**在现代分布式系统中,数据库不仅是数据存储的
java·数据库·python·性能优化·tidb
m0_6784854540 分钟前
如何自动同步SQL异构表数据_利用触发器实现实时数据复制
jvm·数据库·python