一、redis的类型和数据结构到底是怎么回事?
我们常说的redis中有5种数据类型,其实是说的redisObject中的type有5中类型:string,list,hash,set,zset,虽然后面还新增了stream,module这两种类型,但是常用的还是那5种。
然后redisObject还有个encoding字段,定义了它的底层实现。encoding的类型就特别多了如,string会用有的有long,embstr,raw。 然后ziplist,inset,skipList这些数据结构都是在encoding的定义范围之内。
然后,对于redis的key,它一定是用的SDS这个结构的,就是是数值,底层也是用的SDS。
对于value来说,比如set key1 11, 因为值是11,可以转成long,所以会用int编码(编码是int,但是实际是用long存的,只有整数才能用,有小数还是使用SDS)。
一、redis中String结构的底层实现
1. redis是如何实现字符串存储的呢?是用C语言中的char数组实现的吗?
redis中使用的SDS这样个类型来存储字符串的,它的本质还是字符数组,只是在字符数组基础上增加了额外的元数据。在 Redis 中需要用到字符数组时,就直接使用 sds 这个别名。

这里有个小问题?为什么不用char数组,直接保存,而要创建SDS这样一个结构?
原因主要有两个一个是效率问题,比如获取字符串的长度,如果是char数组,你需要通过遍历字符串数组的方式去获取(字符串追加的方法也是一样,需要遍历到字符串尾部,才能追加),SDS直接读取len字段就行。再一个是redis如果想要保存任意的二进制的字符串,使用char数组做不到。因为char数组是通过使用"\0"来标记字符串结束的,所以它没办法保存"\0"这段字符。
二、SDS结构是如何节约内存开销的
SDS 结构中有一个元数据 flags,表示的是 SDS 类型。事实上,SDS 一共设计了 5 种类型,分别是 sdshdr5、sdshdr8、sdshdr16、sdshdr32 和 sdshdr64。这 5 种类型的主要区别就在于,它们数据结构中的字符数组现有长度 len 和分配空间长度 alloc,这两个元数据的数据类型不同。
因为 sdshdr5 这一类型 Redis 已经不再使用了,而sdshdr8、sdshdr16、sdshdr32 和 sdshdr64它们的现有长度 len 和分配空间长度 alloc分别是uint8_t,uint16_t,uint32_t,uint64_t,他们所占的空间大小分别是1个字节,2个字节,4个字节,8个字节。SDS 之所以设计不同的结构头(即不同类型),是为了能灵活保存不同大小的字符串,从而有效节省内存空间。当然这些还需要配合编译优化,不能按默认的8个字节对齐的方式,而是采用紧凑的方式分配内存