5.string字符串
string(字符串)是 Redis 中最简单的数据类型。我们知道,Redis 所有数据类型都是以 key 作为键,通过检索这个 key 就可以获取相应的 value 值。Redis 存在多种数据类型,比如字符串、列表、哈希散列等,它们对应的 value 结构各不相同。本节先讲解字符串的相关知识。
一、认识Redis字符串
Redis 使用标准 C 语言编写,但在存储字符时,Redis 并未使用 C 语言的字符类型,而是自定义了一个属于特殊结构 SDS(Simple Dynamic String)即简单动态字符串),这是一个可以修改的内部结构,非常类似于 Java 的 ArrayList。
1) SDS动态字符串
SDS 的结构定义如下:
struct sdshdr{
//记录buf数组中已使用字符的数量,等于 SDS 保存字符串的长度
int len;
//记录 buf 数组中未使用的字符数量
int free;
//字符数组,用于保存字符串
char buf[];
从上述结构体可以看出,Redis string 将字符串存储到字符类型的buf[]中,并使用 len、free对buf[]数组的长度和未使用的字符数进行描述。
下图展示了 SDS 字符串的结构示意图:
图1
上图 1 存储了一个len为 4 的 “java\0”字符串,并且未使用的字符数free为 0。你可能注意到 buf 数组存储的字符串仍然以 C语言字符格式的“\0”结尾的,这样做的目的是为了能够重用 C语言库 <string.h> 中的部分函数。
在 C语言中,字符串类型的结尾以空字符串 ‘\0’来标识的。但在某些情况下,字符串可能会包含具有实际意义的“空字符”,此时 C语言就无法正确的存取这个字符了,而 Redis 通过 len 来标识字符串的总长度,从而保证了数据的二进制安全特性。
2) 分配冗余空间
string 采用了预先分配冗余空间的方式来减少内存的频繁分配,如下图所示:
图2
如图 2 所示,Redis 每次给 string 分配的空间都要大于字符串实际占用的空间,这样就在一定程度上提升了 Redis string 存储的效率,比如当字符串长度变大时,无需再重新申请内存空间。
3) string自动扩容
当字符串所占空间小于 1MB 时,Redis 对字符串存储空间的扩容是以成倍的方式增加的;而当所占空间超过 1MB 时,每次扩容只增加 1MB。Redis 字符串允许的最大值字节数是 512 MB。
二、Redis字符串命令
1) 命令格式
Redis 提供了操作字符串的命令,通过学习这些命令我们可以掌握如何使用它们,其语法格式如下:
redis 127.0.0.1:6379> COMMAND KEY_NAME
- COMMAND:表示字符串的命令;
- KEY_NAME:表示 key(键)的名称。
在练习命令的过程中,大家要善于利用 Redis 客户端给出的自动语法提示,比如SET命令的格式如下:
127.0.0.1:6379> SET key value [EX seconds|PX milliseconds] [NX|XX]
其中[]内代表可选参数,其含义如下所示:
- EX seconds:设置指定的过期时间,以秒为单位;
- PX milliseconds:设置指定的过期时间,以毫秒为单位;
- NX:先判断 key 是否存在,如果 key 不存在,则设置 key 与 value;
- XX:先判断 key 是否存在,如果 key 存在,则重新设置 value。
SET命令演示:在 key 不存在的情况下设置过期时间为 60s:
#key的过期时间为60s,过期后自动删除
redis 127.0.0.1:6379> SET www.biancheng.net "hello编程帮" EX 60 NX
OK
# 查询 key 对应的值
redis 127.0.0.1:6379> GET www.biancheng.net
"hello编程帮"
2) 常用命令
| 命令 | 说明 |
|---|---|
| SET key value | 用于设定指定键的值。 |
| GET key | 用于检索指定键的值。 |
| GETRANGE key start end | 返回 key 中字符串值的子字符。 |
| GETSET key value | 将给定 key 的值设置为 value,并返回 key 的旧值。 |
| GETBIT key offset | 对 key 所存储的字符串值,获取其指定偏移量上的位(bit)。 |
| MGET key1 [key2..] | 批量获取一个或多个 key 所存储的值,减少网络耗时开销。 |
| SETBIT key offset value | 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。 |
| SETEX key seconds value | 将值 value 存储到 key中 ,并将 key 的过期时间设为 seconds (以秒为单位)。 |
| SETNX key value | 当 key 不存在时设置 key 的值。 |
| SETRANGE key offset value | 从偏移量 offset 开始,使用指定的 value 覆盖的 key 所存储的部分字符串值。 |
| STRLEN key | 返回 key 所储存的字符串值的长度。 |
| MSET key value [key value ...] | 该命令允许同时设置多个键值对。 |
| MSETNX key value [key value ...] | 当指定的 key 都不存在时,用于设置多个键值对。 |
| PSETEX key milliseconds value | 此命令用于设置 key 的值和有过期时间(以毫秒为单位)。 |
| INCR key | 将 key 所存储的整数值加 1。 |
| INCRBY key increment | 将 key 所储存的值加上给定的递增值(increment)。 |
| INCRBYFLOAT key increment | 将 key 所储存的值加上指定的浮点递增值(increment)。 |
| DECR key | 将 key 所存储的整数值减 1。 |
| DECRBY key decrement | 将 key 所储存的值减去给定的递减值(decrement)。 |
| APPEND key value | 该命令将 value 追加到 key 所存储值的末尾。 |
Redis string 的SET/GET命令只能一次设置/查询一个键值对,这样虽然简单,但是效率不高。为了提高命令的执行效率,Redis 提供了可以批量操作多个字符串的读写命令 MSET/MGET(“M”代表“Many”),它们允许你一次性设置或查询多个键值对,这样就有效地减少了网络耗时。
三、简单命令演示
下面对常用命令做简单演示:
1) GETRANGE命令
GETRANGE 命令用于截取一定长度的 value,并返回截取后的新值。语法格式如下:
redis 127.0.0.1:6379> GETRANGE KEY_NAME start end
注意,字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内的闭区间)
示例如下:
127.0.0.1:6379> SET website www.biancheng.net
OK
#索引值
127.0.0.1:6379> GETRANGE website 0 4
"www.b"
#使用负数索引
127.0.0.1:6379> GETRANGE website 0 -1
"www.biancheng.net"
127.0.0.1:6379>
2) GETSET命令
GETSET 命令用于重新设置 value 值,并返回之前旧 value。示例如下:
127.0.0.1:6379> GETSET num first
"6"
127.0.0.1:6379> GETSET num second
"first"
#查看长度值
127.0.0.1:6379> strlen num
(integer) 6
注意:num 之前存储的值为“6”,所以结果返回“6”。
3) SETEX命令
将值 value 存储到 key 中 ,并将 key 的过期时间设为 seconds (以秒为单位)。示例如下:
#设置过期时间为60s
127.0.0.1:6379> SETEX www.biancheng.net 60 hello
OK
#查看过期时间
127.0.0.1:6379> ttl www.biancheng.net
(integer) 5
4) MSETNX命令
该命令了类似于 MSET 命令,但是它仅当指定的 key 不存在时才能够执行成功,用于同时设置多个键值对。示例如下:
#返回0,说明命令执行失败
127.0.0.1:6379> MSETNX www.biancheng.net hello title world
(integer) 0
#删除重复的键
127.0.0.1:6379> del www.biancheng.net
(integer) 1
#重新执行
127.0.0.1:6379> MSETNX www.biancheng.net hello title world
(integer) 1
由于 key 之前已经存在,所以第一次执行失败,当删除存在的后,命令就会执行成功。
5) SETRANGE命令
该命令使用指定的字符在给定的范围内覆盖 key 对应的 value ,其语法格式如下:
redis 127.0.0.1:6379> SETRANGE KEY_NAME OFFSET VALUE
- KEY_NAME:指 key 的名字;
- OFFSET:指初始偏移量;
- VALUE:指要替换成的字符串。
示例如下:
127.0.0.1:6379> SET word "hello world"
OK
127.0.0.1:6379> SETRANGE word 6 www.biancheng.net
(integer) 23
127.0.0.1:6379> GET word
"hello www.biancheng.net"
在线练习工具:https://try.redis.io/
查看更多命令:https://redis.io/commands
5.string字符串的更多相关文章
- Java String字符串/==和equals区别,str。toCharAt(),getBytes,indexOf过滤存在字符,trim()/String与StringBuffer多线程安全/StringBuilder单线程—— 14.0
课程概要 String 字符串 String字符串常用方法 StringBuffer StringBuilder String字符串: 1.实例化String对象 直接赋值 String str=& ...
- [CareerCup] 1.3 Permutation String 字符串的排列
1.3 Given two strings, write a method to decide if one is a permutation of the other. 这道题给定我们两个字符串,让 ...
- 03-Java String字符串详解
1.Java字符串String A.实例化String字符串:直接赋值(更合理一些,使用较多).使用关键字new. B.String内容的比较 // TODO Auto-generated metho ...
- C++学习38 string字符串的增删改查
C++ 提供的 string 类包含了若干实用的成员函数,大大方便了字符串的增加.删除.更改.查询等操作. 插入字符串 insert() 函数可以在 string 字符串中指定的位置插入另一个字符串, ...
- C++学习37 string字符串的访问和拼接
访问字符串中的字符 string 字符串也可以像字符串数组一样按照下标来访问其中的每一个字符.string 字符串的起始下标仍是从 0 开始.请看下面的代码: #include <iostrea ...
- java String字符串——进度1
String字符串 在JAVA中提供了多种创建字符串对象的方法,这里介绍最简单的两种, 第一种是直接赋值, 第二种是使用String类的构造方法: 如下所示: Strin ...
- 关于String字符串反转
这是网上看到的一篇java面试题中的问题: 问题是: 如何将一个String字符串反转. String str = "1234567"; int length = str.leng ...
- JavaScript的内置对象(Date日期+string字符串)基础语法总结
1.Date日期对象可以储存任意一个日期,并且可以精确到毫秒数(1/1000 秒). 1)定义一个时间对象 : var Udate=new Date(); //注意:使用关键字new,Date()的首 ...
- 【转】String字符串相加的问题
String字符串相加的问题 前几天同事跟我说我之前写的代码中在操作字符串时候,使用字符串相加的方式而不是使用StringBuffer或者StringBuilder导致内存开销很大.这个问题一直在困扰 ...
- 从零开始学习前端JAVASCRIPT — 3、JavaScript基础string字符串介绍
1:字符串 JS中的任何数据类型都可以当作对象来看.所以string既是基本数据类型,又是对象. 2:声明字符串 基本数据类型:var sStr = '字符串'; 对象的方法:var oStr = n ...
随机推荐
- 多线程-线程间通信-多生产者多消费者问题解决(notifyAll)
1 package multithread4; 2 3 /* 4 * 生产者,消费者. 5 * 6 * 多生产者,多消费者的问题. 7 * 8 * if判断标记,只有一次,会导致不该运行的线程运行了. ...
- SharedPreferences介绍
sharedPreferences是通过xml文件来做数据存储的. 一般用来存放一些标记性的数据,一些设置信息. 使用sharedPreferences存储数据 ...
- Ajax接收服务器返回的信息response
Ajax可以向服务器发起请求,有去的方式,那么久必然可疑返回. 服务器返回的信息也可以通过Ajax接收. Ajax共有5种状态: 1.创建对象,没有调用open方法 2.对象发起请求http,已经调用 ...
- php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
我们知道数据库处理sql是一条条处理的,假设购买商品的流程是这样的: sql1:查询商品库存 1 if(库存数量 > 0) 2 { 3 //生成订单 4 //库存-1 5 > 当没有并发时 ...
- nginx启动失败:Redirecting to /bin/systemctl start nginx.service Failed to start nginx.service: Unit not found.
解决方法: 是因为nginx没有有添加到系统服务,手动手动添加一个即可. 在 /etc/init.d/下创建名为nginx的启动脚本即可,内容如下: #!/bin/bash # # chkconfig ...
- cmd中删除、添加、修改注册表命令
转自:http://www.jb51.net/article/30586.htm regedit的运行参数 REGEDIT [/L:system] [/R:user] filename1 REGEDI ...
- 如何写出优雅又地道的Python代码?【转载】
在Python社区文化的浇灌下,演化出了一种独特的代码风格,去指导如何正确地使用Python,这就是常说的pythonic.一般说地道(idiomatic)的python代码,就是指这份代码很pyth ...
- Solution -「BZOJ #3786」星系探索
\(\mathcal{Description}\) Link. 给定一棵含 \(n\) 个点的有根树,点有点权,支持 \(q\) 次操作: 询问 \(u\) 到根的点权和: 修改 \(u\) ...
- Solution -「SV 2020 Round I」「SRM 551 DIV1」「TC 12141」SweetFruits
\(\mathcal{Description}\) link. 给定 \(n\) 个水果,每个结点可能有甜度 \(v_i\),或不甜(\(v_i=-1\)).现在把这些水果串成一棵无根树.称一 ...
- 主机磁盘使用率超过85%导致es索引变为只读模式
[ type=cluster_block_exception, reason=index [ index_name ] FORBIDDEN/12/index read-only / allow del ...