SDS 简单动态字符串
背景介绍
Redis数据库里面的每个键值对都是有对象组成的,数据库的键总是一个字符串对象(String Object); 而数据库键的值则可以使字符串对象、列表对象(list object)、哈希对象(hash object)、集合对象(set object)、有序集合对象(sorted set object)。
SDS
Redis使用SDS(simple dynamic string, SDS)的抽象类型来作为默认的字符串,它是一个二进制数组。
struct sdshdr {
// 记录buf数组中已使用字节的数量
// 等于SDS所保存字符串的长度
int len;
// 记录仪buf数组中未使用字节的数量
int free;
// 字节数组,用于保存字符串
char buf[];
}
可以看到,这样设计与原生C字符串相比的优点:
- O(1)获取字符长度,这对于频繁获取字符串长度操作的STRLEN命令,很重。
- 由于有预先分配的未使用空间,一定程度上缩减了字符串变长时的内存重分配次数。即便字符串变短时,它也不会立马缩减,为将来有可能增长的操作提供了优化。但同时SDS也提供了API,方便我们在需要的时候释放SDS的未使用空间,不用担心这种释放策略会造成内存浪费。
- 相比C字符串受限于编码,除了字符串的末尾,不能包含空字符串,所以不能保存图片、音频、视频、压缩文件这样的二进制数据。SDS都可以,是真正的二进制数组。
缺点:当然就是空间的增大,典型的空间换时间,因为Redis就是要快!其实现的思想可以类比Java ArrayList。