Redis字符串类型为何能存整数,浮点型甚至是二进制位(使用SETBIT等命令)

Redis没有直接使C语言传统的的字符串(以空字符串结尾的字符数组,简称C字符串),而是本身构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型,并将SDS用做Redis的默认字符串表示。redis

好比,客户端执行命令:数据库

redis>SET msg "hello world";
ok
复制代码

那么Redis将在数据库中建立两个SDS分别存储键和值。api

SDS的定义

每一个sds.h/sdshrd结构表示一个SDS值:数组

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

因此上面set msg "hello world",值在的SDS中的样子以下: 安全

hello world的SDS
SDS遵循C语言以空字符串结尾的惯例,保存空字符串的一个字节不计算在len属性当中,而且为空字符串分配额外的一个字节空间,以及添加空字符串到字符串末尾等操做,都是由SDS函数自动完成的。遵循空字符串结尾这一特性的好处是能够复用一部分C字符串函数库中的函数。

常数复杂度获取字符串长度

C字符串获取长度须要遍历整个字符串,复杂度为O(N),而是用SDS的话,由于使用了一个len属性来记录字符串长度,因此获取长度的复杂度为O(1)。bash

SDS 其余特性这里暂不介绍

二进制安全

C字符串中的字符必须符合某种编码(好比ASCII),而且除了字符串的末尾以外,字符串里面不能包含空字符串,不然最早被程序读入的空字符串会被误认为是字符串末尾,这些限制使得C字符串只能保存文本数据,不能保存像图片、音频、视频等这样子的二进制数据。函数

Redis中的SDS的api都是二进制安全的,会以二进制的方式来处理SDS存放buf数组里的数据,程序不会对其中的数据作任何限制、过滤等,数据在写入时是什么样的,它被读取时就是什么样子。编码

使用SDS来保存以前提到的特殊数据格式(好比音频,视频等)就没有任何问题,由于SDS使用len属性的值而不是字符串来判断字符串是否结束。因此使用二进制安全的SDS,使得Redis不只考验保存文本数据,还能够保存任意格式的二进制数据。spa

参考书籍:《Redis设计与实现》设计

相关文章
相关标签/搜索