Redis五大基本数据类型

Redis作为高性能的键值存储系统,其核心价值在于丰富的数据结构。本文将深入剖析Redis的五种基本数据类型,揭示其内部实现原理,并提供实际应用场景和最佳实践。

一、字符串(String):Redis的基石

底层实现

Redis字符串使用简单动态字符串(SDS) 结构:

struct sdshdr {
    int len;      // 已使用长度
    int free;     // 未使用空间
    char buf[];   // 字节数组
};

优势特性

  • O(1)时间复杂度获取长度

  • 自动扩容机制(小于1MB时加倍,大于1MB时每次加1MB)

  • 二进制安全(可存储任意格式数据)

核心命令详解

命令 时间复杂度 使用示例 说明
SET O(1) SET user:1001 "Alice" 设置键值
GET O(1) GET user:1001 获取值
INCR O(1) INCR article:2001:views 原子递增
SETEX O(1) SETEX session:xyz 3600 "data" 设置带过期时间的值
MSET O(N) MSET key1 "v1" key2 "v2" 批量设置
GETRANGE O(N) GETRANGE text 0 4 获取子串

二、哈希(Hash):对象存储利器

底层实现

Redis哈希使用两种编码方式

  • ziplist(元素数量<512且值<64字节)

  • hashtable(其他情况)

// ziplist结构示例
[ zlbytes | zltail | zllen | "name" | "Alice" | "age" | "30" | zlend ]

核心命令详解

命令 时间复杂度 示例 说明
HSET O(1) HSET user:1001 name "Alice" 设置字段
HGET O(1) HGET user:1001 name 获取字段
HGETALL O(N) HGETALL user:1001 获取所有字段
HDEL O(1) HDEL user:1001 email 删除字段
HINCRBY O(1) HINCRBY user:1001 age 1 数值增加
HSCAN O(1) HSCAN user:1001 0 渐进式遍历

实战应用

  1. 用户档案存储

HSET user:1001 name "Alice" email "[email protected]" age 30
  1. 商品购物车

HINCRBY cart:1001 item:5001 2  # 添加2件商品5001
HGETALL cart:1001

    三、列表(List):消息队列核心

    底层实现

    Redis列表使用快速列表(quicklist)

    struct quicklist {
        quicklistNode *head;
        quicklistNode *tail;
        unsigned long count; // 元素总数
        // ...
    };
    
    struct quicklistNode {
        quicklistNode *prev;
        quicklistNode *next;
        unsigned char *zl;   // 指向ziplist
        // ...
    };

    核心命令详解

    命令 时间复杂度 示例 说明
    LPUSH O(1) LPUSH news:latest 1001 左端插入
    RPOP O(1) RPOP task:queue 右端弹出
    LINDEX O(N) LINDEX news:latest 0 获取元素
    LRANGE O(S+N) LRANGE chat:1001 0 9 范围获取
    BLPOP O(1) BLPOP order:queue 30 阻塞弹出
    LTRIM O(N) LTRIM chat:1001 0 99 保留指定范围

    应用场景

    1. 消息队列系统

    # 生产者
    LPUSH order:queue "{\"id\":1001,\"amount\":99.9}"
    
    # 消费者
    BRPOP order:queue 30

    四、集合(Set):无序唯一集合

    底层实现

    Redis集合使用两种编码:

    • intset(元素均为整数且数量<512)

    • hashtable(其他情况)

    struct intset {
        uint32_t encoding; // 编码方式(INTSET_ENC_INT16等)
        uint32_t length;   // 元素数量
        int8_t contents[]; // 元素数组
    };

    核心命令详解

    命令 时间复杂度 示例 说明
    SADD O(1) SADD tags:2001 "tech" 添加元素
    SISMEMBER O(1) SISMEMBER tags:2001 "news" 检查存在
    SMEMBERS O(N) SMEMBERS user:1001:followers 获取所有成员
    SINTER O(N*M) SINTER group:1 group:2 交集
    SUNION O(N) SUNION group:1 group:2 并集
    SSCAN O(1) SSCAN user:1001:followers 0 渐进式遍历

    五、有序集合(Sorted Set):排行榜核心

    底层实现

    Redis有序集合使用两种结构:

    • ziplist(元素数量<128且值<64字节)

    • 跳跃表+字典(其他情况)

    struct zskiplistNode {
        sds ele;                 // 成员
        double score;            // 分值
        struct zskiplistNode *backward; // 后退指针
        struct zskiplistLevel {
            struct zskiplistNode *forward; // 前进指针
            unsigned long span; // 跨度
        } level[];
    };
    
    struct zset {
        dict *dict;              // 字典:成员->分值
        zskiplist *zsl;          // 跳跃表
    };

    核心命令详解

    命令 时间复杂度 示例 说明
    ZADD O(logN) ZADD leaderboard 100 "Alice" 添加成员
    ZRANGE O(logN+M) ZRANGE leaderboard 0 2 WITHSCORES 范围查询
    ZREVRANK O(logN) ZREVRANK leaderboard "Alice" 获取排名
    ZSCORE O(1) ZSCORE leaderboard "Alice" 获取分数
    ZUNIONSTORE O(NK)+O(MlogM) ZUNIONSTORE out 2 set1 set2 WEIGHTS 2 3 有序集合并
    ZRANGEBYSCORE O(logN+M) ZRANGEBYSCORE salary 3000 5000 按分数范围查询

    你可能感兴趣的:(redis,数据库,缓存,java)