Redis数据结构

Redis 是用 C 语言开发的一个开源的高性能非关系型数据库,大多数情况下数据存储在内存中,因此其读写速度相比基于磁盘的关系型数据库快。由于其速度快的特点所以被广泛应用在缓存方面,它支持多种数据类型如字符串、列表、集合、有序集合、哈希等。

  1. String
    String(字符串)是 Redis 中最基本的数据类型,以 key-value 的形式存在,其具有二进制安全(可存图片、序列化对象)的特点,可以正确存储二进制数据。最大可存储 512MB 的数据。一个 key 只能对应一个 value。数据未获取到时,对应的数据为(nil),等同于null。String 存储的内容通常为字符串,如果字符串以整数的形式展示,可以作为数字使用 incr/decr 命令操作使用.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    # 存入
    set key value
    # 查询
    get key
    # 删除 [如果键被删除成功,命令执行后输出(integer) 1,否则将输出(integer) 0]
    del key

    # 数值操作-加一
    incr key
    # 数值操作-减一
    decr key

    # 存入,设置1000秒后过期
    set key1 1 ex 1000

    # 替换并返回原key
    getset key value

    # 不存在时才写入
    setnx key value

    # 批量存入
    mset key1 value1 key2 value2 ... keyn valuen
    # 批量查询
    mget key1 key2 ... keyn

    # 设置过期时间
    expire key seconds

    # 返回key的长度
    STRLEN key

    # 将值 value 关联到 key ,并将 key 的过期时间设为 seconds 秒。
    setex key seconds value

    # 追加信息
    append key value
  2. Hash
    Hash 是 String 元素组成的字典集,是一个 String 类型的 field 和 value 的映射表。Hash 特别适合用于存储对象,每个 Hash 可以存储 2^32-1 键值对。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 存入
    hget hashkey field value
    # 批量存入
    hmset hashkey field1 "Hello" field2 "World"

    # 查询
    hget hashkey field
    # 批量查询
    hmget hashkey field1 field2 ... fieldn
  3. List
    List 是简单的字符串链表(双向),基于压缩列表和链表实现。按照插入顺序排序,增删快。可以添加一个元素到列表的头部(左边)或者尾部(右边)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #存入
    lpush listkey redis
    #(integer) 1
    lpush listkey mongodb
    #(integer) 2
    lpush listkey rabbitmq
    #(integer) 3

    #查询
    lrange listkey 0 10
    #1) "rabbitmq"
    #2) "mongodb"
    #3) "redis"

  4. Set
    Set 是 String 类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1),且提供交集、并集、差集的操作。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #存入
    sadd setkey redis
    #(integer) 1 成功
    sadd setkey mongodb
    #(integer) 1 成功
    sadd setkey rabbitmq
    #(integer) 1 成功
    sadd setkey rabbitmq
    #(integer) 0 失败,已存在,集合内元素唯一,被忽略

    #查询
    smembers setkey
    #1) "redis"
    #2) "rabbitmq"
    #3) "mongodb"
  5. zSet
    zSet 和 Set 一样也是 String 类型元素的集合,且不允许重复的成员,每个元素都会关联一个double类型的分数。zSet的成员是唯一的,但分数(score)却可以重复。由于其插入数据时会将数据排序,适用于排行榜、带权重的消息队列。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #zadd key score member

    #存入
    zadd zsetkey 0 redis
    #(integer) 1 成功
    zadd zsetkey 0 mongodb
    #(integer) 1 成功
    zadd zsetkey 0 rabbitmq
    #(integer) 1 成功
    zadd zsetkey 0 rabbitmq
    #(integer) 0 失败,已存在

    #查询
    ZRANGEBYSCORE zsetkey 0 1000
    #1) "mongodb"
    #2) "rabbitmq"
    #3) "redis"

如何使用 zSet 实现排行榜?将每个用户的得分作为 zSet 中元素的 score ,将用户ID作为元素的 member。使用 zSet 提供的排序功能,可以按照分数从高到低排序展示。但是如果分数相同,按照默认的排序规则会按照 value 值排序而不是按照时间。

为了实现分数相同按照时间顺序从大到小排序,可以将分数 score 设置为一个浮点数,其中整数部分为得分,小数部分为时间戳,最终得分 finalscore = score + timestamp/1e13,如果需要同分数按时间戳从小到大展示排行榜,则最终得分 finalscore = score + 1 - timestamp/1e13

举例:分数为10,当前时间戳为 1622106372468,那么最终得分 10.1622106372468

  1. Stream
    Stream 是 Redis 5.0 中新增加的一种数据结构,可以被视为一个日志或消息队列,其中每个消息都有一个唯一的ID,并且按照添加的顺序进行排序。可以向 Stream 中添加消息、读取消息、删除消息以及订阅消息。Stream数据结构还支持消费者组,可以让多个消费者并发地处理消息流。

在 Redis 5.0 之前,通过Redis的发布订阅 (pub/sub) 可以实现消息队列的功能,但这种操作有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃导致消息丢失。

  1. 其它及扩展插件

Bitmap位图、HyperLogLog计数、Geo位置信息等等数据结构,这些数据结构在默认参数编译或启动的 Redis 中并不存在,需要修改配置文件加载扩展库,或自行编译 Redis 后才可以使用。