Skip to content

Latest commit

 

History

History
146 lines (97 loc) · 4.11 KB

1.基本数据类型.md

File metadata and controls

146 lines (97 loc) · 4.11 KB

redis中有五种常见数据类型: string、list、set、zset、hash, 也是学习和深入redis的第一篇, 本篇文章将从这几种类型最基本使用方法、使用场景方面,以及底层数据结构这两方面学习总结学习redis的基本数据类型

开篇我先介绍其中有用到的数据结构,对于底层结构有了认识之后,再结合每个基本数据类型的介绍,让大家看完能更加深刻

底层数据结构

关于底层数据结构大概有如下几个

  • sds
  • 双向链表
  • 压缩链表
  • 字典
  • 整数集合
  • 压缩列表

下面一一进行介绍学习

sds

  • 基本类型string、协议内容、aof缓存、返回给客户端的回复, 都是sds

Redis中string实现没有沿用C语言中的string类型,而是用自己实现的sds结构,原因如下几点:

  1. string类型**获取长度时需要O(n)**时间复杂度从头开始遍历一次,直到遇到\0结束
  2. string类型中如果有\0那么会提前结束,产生问题,在redis.string支持多类型内容存储的情况下,不免中间会有\0, 这样会产生问题

redis/s rc/sds.h中关于sds结构声明如下:

/* Note: sdshdr5 is never used, we just access the flags byte directly.
 * However is here to document the layout of type 5 SDS strings. */
struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

(sdshdr8、sdshdr16这些还没搞明白, 不同大小 len、分配大小用不同类型表示 为优化空间?)

  • len: 字符串真正的长度(不包含空终止字符)
  • alloc: 字符串的最大容量,不包含 header 和最后的 '0',初始时与 len 值一致
  • flags: 低三位表示 header 类型
  • buf: 柔性数组,表示一个长度动态的字符串

优化追加/扩容

双向链表

压缩链表

跳跃表

---- 深入了解Redis底层数据结构

  • 多层的结构组成,每层是一个有序的链表
  • 最底层(level 1)的链表包含所有的元素
  • 跳跃表的查找次数近似于层数,时间复杂度为O(logn),插入、删除也为 O(logn)
  • 跳跃表是一种随机化的数据结构(通过抛硬币来决定层数)

字典

整数集合

基本数据类型

string

基于sds实现的string类型, O(1)的长度获取, 支持多种类型存储(base64图片等)

使用方法

  • set
  • get
  • setex

使用场景

list

  • 数据少时-- 压缩链表
  • 达到阈值时 -- 双向链表

使用方法

使用场景

set

  • 整数集合实现

使用方法

使用场景

zset

---- zset底层实现

  • 字典+跳跃表
  • 压缩链表

使用方法

使用场景

hash

  • 字典HashTable
  • 压缩链表

使用方法

使用场景

参考