Redis的Key永远都是string类型,nil代表null

具体的底层实现原理可以参考书籍《Redis设计与实现》

Value的五种常用数据类型
类型类似于Java的
stringString
hashHashMap
listLinkedList
setHashSet
sorted_setTreeSet

1 string类型

最常用也最简单的数据存储类型,一个存储空间保存一个数据。整数字符串可以作为数字操作使用。

底层实现

每个string类型的结构如下:

struct sdshdr{
    // 记录buf数组中已使用字节的数量等于SD所保存字符串的长度
    int len;
    // 记录buf数组中未使用字节的数量
    int free;
    // 字节数组,用于保存字符串
    char buf[];
}
基本操作
操作格式
添加/修改数据set key value
添加修改多个数据mset key1 value1 key2 value2
获取数据get key
获取多个数据mget key1 key2
删除数据(返回integer 1或者0)del key
获取数据字符个数(string的length)strlen key
追加信息到字符串后面(没有就新建,返回length值)append key value

set和mset要因地制宜的使用,并没有哪个更好的道理。

string类型数字数据的拓展操作

1.给数字字符串数据增加值

指令说明
incr key+1
incrby key increment+指定的值(只能为整数)
incrbyfloat key increment+指定的小数的值

2.给数字字符串减少值

指令说明
decr key-1
decrby key increment不说了

注意:数字类型最大等同于Java的Long.MAX_VALUE

数据时效性设置
指令说明
setex key seconds value设置某个key的生命周期为指定秒
psetex key milliseconds value指定毫秒
key的设置约定

数据库中的key命名惯例:

表名:主键名:主键值:字段名

2 Redis hash类型

一个存储空间保存多个键值对数据,底层使用哈希表结构实现数据存储

hash存储结构优化
  • 如果field数量较少,存储结构优化为类数组结构
  • 如果field数量较多,存储结构使用HashMap结构
key -> { field1 : value1
         field2 : value2
         field3 : value3
         ...        
        }
基本操作
操作说明
hset key field value添加和修改数据
hget key field获取数据
hgetall key按key获取所有数据
hdel key field1 [field2]删除数据
hmset key field1 value1 field2 value2添加和修改多个数据
hmget key field1 field2 ...get多个数据
hlen key获取哈希表中field-value的数量
hexists key field获取哈希表中是否存在指定的字段
拓展操作
操作说明
hkeys key获取key中的所有field
hvals key获取key中的所有value
hincrby key field increment按值增加value数值
hincrybyfloat key field increment还是增加(小数OK)
注意事项
  • hash类型下的value只能存储string类型,不能嵌套一个hash什么的
  • 如果没获取到对应的值为nil
  • 每个hash可以存储2^32-1个键值对
  • hgetall如果内部field过多,则效率会很低(为啥呢?),可能成为数据访问瓶颈
应用场景举例

电商网站购物车的设计与实现(简单版)

  • key:用户id
  • field:商品id和数量以及各种其他的信息
  • value:商品购买数量

实现操作

  • 添加商品:增加全新的field和value
  • 游览购物车:遍历hash
  • 更改数量:自增/自减,设置value值
  • 删除商品:删除field
  • 清空:删除key

例如:

g01:nums 100 g01:info{json表单} ...

拓展操作:

hsetnx key field value

添加前判断是否已经存在field,如果存在则不添加,不存在则添加

3 list类型

特点
  • 底层使用带头尾指针的无环双向链表
  • 带链表长度计数器unsigned long len
  • 链表可以保存各种不同类型的值
  • 头尾指针都指向null,对链表的访问以null为终点
底层实现

每一个链表结点的定义如下:

typedef struct listNode{
    //前置节点
    struct listNode *prev;
    //后置节点
    struct listNode *next;
    //节点的值
    void *value;
}listNode;

每个链表的定义如下:

typedef struct list{
    //表头节点
    listNode *head;
    //表尾结点
    listNode *tail;
    //链表所包含的节点数量
    unsigned long len;
    //节点值赋值函数
    void *(*dup) (void *ptr);
    //节点值释放函数
    void (*free) (void *ptr);
    //节点值对比函数
    int (*match) (void *ptr,void *key);
} list;
基本操作
操作说明
lpush key value1 [value2] ...从左边插入新节点
rpush key value1 [value2]...从右边插入新节点
lrange key start stop按索引范围获取
lindex key index按索引获取
llen key获取长度
lpop key删除最左的节点
rpop key删除最右的节点
拓展操作
操作说明
blpop key [key2] timeout等待timeout秒数之后,直到能从左边pop出来key(block left pop)
brpop key [key2] timeout等待指定秒数,直到能从右边取出
lrem key count value从左边数删除count个指定的value
注意事项
  • list节点量最大为2^32-1个元素
  • 可以按索引取数,但一般用pop方式取数(毕竟时间复杂度低)
  • 可以实现对数据进行分页操作

4 set类型

存储需求:存储大量的数据,并且能够提供高效率的查询

特点:

  • 对应的hash存储结构中只有key,没有value(value为nil)
  • Redis里面的value就是set类型的key
  • 因为索引不能重名,所以value是不可以重复的(不会覆盖,直接不允许)
  • 可以应用于同类数据的自动快速去重添加、自动制作黑白名单等
基本操作
操作说明
sadd key member1 [member2]添加数据
smembers key获取全部数据
srem key member1 [member2]删除数据
scard key获取集合数据总量
sismember key member判断是否存在指定数据
拓展操作
操作说明
srandmember key [count]随机从key中取一个(或者几个)数据
spop key随机获取一个并且移除
集合相关操作
操作说明
sinter key1 [key2]求并集
sunion key1 [key2]求交集
sdiff key1 [key2]求差集
sinterstore destination key [key2]求并集并存到新的集合中
sunionsotre, sdiffsotre同理
smove source destination member把member从指定集合移到另一个集合中

5 sorted_set类型

底层结构

在set的存储结构基础上添加可排序字段来实现(字典)

结构:

hash:        key  : value
sorted_set: value: 排序字段
set:        value: (nil)
基本操作
操作说明
zadd key score1 member1添加数据,score为排序字段,member为值
zrange key start stop [withscores]按索引起始获取全部数据[顺带score一起输出]
zrevrange key start stop [withscores]和上面相比为按score降序输出
zrem key member删除数据
zrangebyscore key min max [withscores] [limit]按条件查询,(limit后面接个数范围)
zrevrangebyscore key max min [withscores]按条件查询逆序输出
zremrangebyrank key start stop按索引删除
zremrangebyscore key min max按排序顺序删除
集合相关操作
操作说明
zcard key获取集合数据总量
zcount key min max获取指定大小区间的数据总量
zinterstore destination numkeys key求交集并存入destination
zunionstore destination numkeys key求并集并存入destination
拓展操作
操作说明
zrank key member升序输出排名
zrevrank key member降序输出排名
zscore key member输出score值
zincrby key increment member给指定member的score值+1
注意事项
  • score保存的数据存储空间为64位
  • score可以为双精度的double值(可能会丢失精度)
  • sorted_set底层存储还是基于set结构的,因此数据不能重复,如果重复了key,则会覆盖掉score
Last modification:May 11th, 2021 at 10:04 pm