Redis五大基本数据类型

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

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

底层实现

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

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

优势特性

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

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

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

核心命令详解

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

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

底层实现

Redis哈希使用两种编码方式

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

  • hashtable(其他情况)

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

核心命令详解

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

实战应用

  1. 用户档案存储

HSET user:1001 name "Alice" email "alice@example.com" 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
        // ...
    };

    核心命令详解

    命令时间复杂度示例说明
    LPUSHO(1)LPUSH news:latest 1001左端插入
    RPOPO(1)RPOP task:queue右端弹出
    LINDEXO(N)LINDEX news:latest 0获取元素
    LRANGEO(S+N)LRANGE chat:1001 0 9范围获取
    BLPOPO(1)BLPOP order:queue 30阻塞弹出
    LTRIMO(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[]; // 元素数组
    };

    核心命令详解

    命令时间复杂度示例说明
    SADDO(1)SADD tags:2001 "tech"添加元素
    SISMEMBERO(1)SISMEMBER tags:2001 "news"检查存在
    SMEMBERSO(N)SMEMBERS user:1001:followers获取所有成员
    SINTERO(N*M)SINTER group:1 group:2交集
    SUNIONO(N)SUNION group:1 group:2并集
    SSCANO(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;          // 跳跃表
    };

    核心命令详解

    命令时间复杂度示例说明
    ZADDO(logN)ZADD leaderboard 100 "Alice"添加成员
    ZRANGEO(logN+M)ZRANGE leaderboard 0 2 WITHSCORES范围查询
    ZREVRANKO(logN)ZREVRANK leaderboard "Alice"获取排名
    ZSCOREO(1)ZSCORE leaderboard "Alice"获取分数
    ZUNIONSTOREO(NK)+O(MlogM)ZUNIONSTORE out 2 set1 set2 WEIGHTS 2 3有序集合并
    ZRANGEBYSCOREO(logN+M)ZRANGEBYSCORE salary 3000 5000按分数范围查询
    ### Redis 五种基本数据结构及其用法 #### 1. **String(字符串类型)** String 类型是最简单的键值对存储方式,其值可以是一个普通的字符串或者二进制安全的字节序列。它支持的操作不仅限于设置和获取值,还可以执行原子操作如自增或自减计数值。 - 常见命令: - `SET key value` 设置指定键的值。 - `GET key` 获取指定键的值。 - `INCR key` 对键对应的整数值加一。 - `DECR key` 对键对应的整数值减一。 - 使用场景:缓存小型数据、计数器等[^1]。 ```python # Python 示例代码 import redis r = redis.Redis(host='localhost', port=6379, decode_responses=True) r.set('name', 'Alice') # SET name Alice print(r.get('name')) # GET name -> 输出: Alice ``` --- #### 2. **Hash(哈希类型)** Hash 数据结构用于存储字段与值之间的映射关系,适合表示对象属性。它的特点是可以通过单个命令高效地访问某个特定字段的值。 - 常见命令: - `HSET key field value` 将哈希表中的字段设为指定值。 - `HGET key field` 取得储存在哈希表中指定字段的值。 - `HMSET key field1 value1 [field2 value2 ...]` 同时将多个字段/值对设置到哈希表中。 - `HGETALL key` 返回整个哈希表的内容。 - 使用场景:存储用户信息或其他具有多属性的对象。 ```python # Python 示例代码 r.hset('user:1000', mapping={'name': 'Bob', 'age': 25}) print(r.hgetall('user:1000')) # 输出 {'name': 'Bob', 'age': '25'} ``` --- #### 3. **List(列表类型)** List 是一个有序的字符串列表,可以在两端进行高效的插入和移除操作。由于其实现基于双向链表,因此非常适合处理队列类的任务。 - 常见命令: - `LPUSH key element` 在列表头部插入元素。 - `RPUSH key element` 在列表尾部插入元素。 - `LPOP key` 移除并返回列表的第一个元素。 - `RPOP key` 移除并返回列表的最后一个元素。 - 使用场景:消息队列、最近浏览记录等功能。 ```python # Python 示例代码 r.lpush('queue', 'task1') r.rpush('queue', 'task2') print(r.lrange('queue', 0, -1)) # 查看当前队列内容 ['task2', 'task1'] ``` --- #### 4. **Set(集合类型)** Set 存储的是唯一且无序的字符串元素集,内部通过哈希表来实现,从而保证了常量时间复杂度下的查找效率。 - 常见命令: - `SADD key member [member ...]` 添加一个或多个成员至集合。 - `SMEMBERS key` 列举集合内的所有成员。 - `SCARD key` 统计集合内有多少个成员。 - `SDIFF key [key ...]` 找出第一个集合与其他集合的不同之处。 - 特点:去重功能强大,适用于好友推荐等领域[^4]。 ```bash DEL student (integer) 1 sadd student alice (integer) 1 sadd student bob (integer) 1 smembers student # 结果可能顺序不同 ["alice", "bob"] ``` --- #### 5. **Sorted Set(有序集合类型)** Sorted Set 和 Set 都能保存不重复的成员,但前者还附加了一个分数(score),使得它可以按照分值排序展示出来。 - 常见命令: - `ZADD key score member [score member ...]` 插入带有权重的新条目。 - `ZRANGE key start stop [WITHSCORES]` 按照索引范围提取部分成员以及它们各自的得分。 - `ZREM key member [member ...]` 删除某些已存在的项目。 - 应用实例:排行榜系统设计[^5]。 ```python # Python 示例代码 r.zadd('leaderboard', {'player1': 150, 'player2': 300}) print(r.zrange('leaderboard', 0, -1, withscores=True)) # [(b'player1', 150), (b'player2', 300)] ``` --- ### 总结 Redis 中的所有数据均以 Key-Value 形式储存,其中 Value 的具体表现形式由上述提到的各种数据类型决定[^2]。此外,跳跃表技术被用来管理 Sorted Sets 的层级高度上限问题,确保性能稳定[^3]。
    评论
    成就一亿技术人!
    拼手气红包6.0元
    还能输入1000个字符
     
    红包 添加红包
    表情包 插入表情
     条评论被折叠 查看
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值