redis 的string类型其最基本的一种数据类型,英文全称(simple dynamic strings)简单动态字符串;redis的其余数据类型都是基于其之上!最大存储512MB;即可存储简单的字符串,也可存储复杂的json/xml,甚至二进制的图像 音频字符串!
一,作用
一是存储字符串对象,简介中已经说明;
二是redis内部也使用了string数据结构用于替换c语言中的char*;看到这里我们不禁要思考,redis为什么不适用c语言的char*类型呢?因为char类型比较单一,不能动态的追加数据,获取长度!而在sds中完美了解决了这些问题!
二,实现
typedef char *sds;
struct sdshdr {
// buf 已占用长度
int len;
// buf 剩余可用长度
int free;
// 实际保存字符串数据的地方
char buf[];
};
其中,类型 sds 是 char * 的别名(alias),而结构 sdshdr 则保存了 len 、 free 和 buf 三个属性。
作为例子,以下是新创建的,同样保存 hello world 字符串的 sdshdr 结构:
struct sdshdr {
len = 11;
free = 0;
buf = "hello world\0"; // buf 的实际长度为 len + 1
};
通过 len 属性, sdshdr 可以实现复杂度为 θ(1) 的长度计算操作。
另一方面, 通过对 buf 分配一些额外的空间, 并使用 free 记录未使用空间的大小, sdshdr 可以让执行追加操作所需的内存重分配次数大大减少, 下一节我们就会来详细讨论这一点。
当然, sds 也对操作的正确实现提出了要求 —— 所有处理 sdshdr 的函数,都必须正确地更新 len 和 free 属性,否则就会造成 bug 。
string是简单动态字符串 如果说 len 属性 让我们获取其长度变得简单 ,那么 free属性 就是让其动态的原因! free是空余的空间,内存中我们的空间是按字节去存储的 , 上段代码中 buf 中的 hello world 在C中实际是是一位 是因为 C语言中是以/0结尾; free默认18个字节为一个空间, 那么我们再次追加 将buf改变为 hello world xiaolaohu! 会发生什么变化呢?
redis> SET msg "hello world"
OK
redis> APPEND msg " xiaolaohu!"
(integer) 18
redis> GET msg
"hello world xiaolaohu!"
当执行 APPEND 命令时,相应的 sdshdr 被更新,字符串 " xiaolaohu!" 会被追加到原来的 “hello world” 之后:
struct sdshdr {
len = 21;
free = 15;
buf = "hello world xiaolaohu!\0 "; // 空白的地方为预分配空间,共 18 + 18 + 1 个字节
}
此时发现 sds为期增加了18个字节的空间
所以在使用string的时候 我们需要注意 这一点 否则可能会因此浪费不必要的空间
三,应用场景
一是session的分散管理
截图的两种方法都可
二是商品的计数器 点赞数 浏览数 都可,因为string的自增是原子性的,所以是比较安全的
INCR key
将 key 中储存的数字值增一。
三是可用于特定接口限速
string 命令表