玖叶教程网

前端编程开发入门

redis基本数据类型

字符串-String

字符串类型是redis的基础数据类型。首先,键都是字符串类型。字符串类型的值可以是字符串(简单字符串或者JSON/XML)、数值(整数和浮点数),二进制(图片,音频和视频),但是最大不能超过512MB。

数据结构

redis字符串使用SDS结构存储。

我们都知道redis是使用C语言编写的,那么字符串为什么不使用C语言的字符串而要自己定义一套SDS结构呢,相比于C语言的字符串SDS结构有如下优点:

1、查询复杂度低,O(1)

2、自定义结构,封装自己字符串处理函数,可以处理\0

3、预分配空间和惰性回收减少系统调用和内存碎片

常见指令

set:set key value 设置值

setnx:setnx key value 只有在key不存在值时才能设置成功

get:get key 获取指定key的值

getrange key start end 返回字符串指定的子字符串,从0开始

mget:mget key1 key2 获取多个key的值

getset:getset key value 给指定的key设置新值并返回旧值

getbit:getbit key offset 获取key对应字符串对应offset偏移量上的位(二进制)

setbit:setbit key offset value 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)

setex:setex key seconds value 设置key值并指定过期时间,单位为秒

setrange:setrange key offset value 指定位置替换值

strlen:返回key 所储存的字符串值的长度

mset:mset key value key value 同时设置多个键值对

msetnx:同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。

psetex:psetex key mis value 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位

incr:key中的值加一

incrby:key in 值加上指定值

decr:作用与incr相反

decrby:作用与incrby相反

append:字符串追加值

场景

1、缓存;可以存储字符串、数值、图片、系列化的对象

2、利用setnx的特性设计分布式锁

3、利用incr、incrby、decr、decrby设计计数器

3、共享数据

哈希-Hash

数据结构

redis哈希存储有两种数据结构:dict和zipList

当hash对象可以同时满足一下两个条件时,哈希对象使用ziplist编码:

1.哈希对象保存的所有键值对的键和值的字符串长度都小于64字节

2.哈希对象保存的键值对数量小于512个

dict

typedf struct dict{
    
    // 类型特定函数,包括一些自定义函数
    // 这些函数使得key和value能够存储
    dictType *type;
    
    // 私有数据
    void *private;
    
    // 两张hash表 
    dictht ht[2];
    
    // rehash索引,字典没有进行rehash时,此值为-1
    int rehashidx;
    
    // 正在迭代的迭代器数量
    unsigned long iterators; 
    
}dict;
typedf struct dictht{

    // 存储数据的数组 二维
    dictEntry **table;
    
    // 数组的大小
    unsigned long size;
    
    // 哈希表的大小的掩码,用于计算索引值
    // 总是等于 size-1
    unsigned long sizemask;
    
    // 哈希表中中元素个数                      
    unsigned long used;
    
}dictht;
typedf struct dictEntry{

    // 键
    void *key;
    
    // 值
    union{
        void val;
        unit64_t u64;
        int64_t s64;
        double d;
    }v;
    
    // 指向下一个节点的指针
    struct dictEntry *next;
    
}dictEntry;

dict主要使用两张hash表存储数据,hash表中定义entity数据<k,value>的结构存储key和value的值,采用两张hash表的形式进行扩容和rehash,可参考https://blog.csdn.net/qq_33333654/article/details/127212465进行了解。

常用指令

hdel:hdel key field1 field2 删除一个或多个hash表的字段

hexists:hexists key field 查看key中指定的字段是否存在,存在返回1否则返回0

hget:hget key field 获取key中指定的filed字段的值

hgetall:hgetall key 获取key中所有字段和值

hincrby:hincrby key filed inc 哈希表 key 中的指定字段的整数值加上增量 increment

hkeys:hkeys key获取哈希表中的所有字段

hlen:hlen key 获取哈希表中字段的数量

hmget:hmget key field1 field2 获取所有给定字段的值

hmset:hmset key field value field1 value 将多个字段和值设置给指定的key

hset:hset key field value 设置值

hsetnx:只有在字段 field 不存在时,设置哈希表字段的值。成功返回1,失败返回0

hvals:获取哈希表中所有值

场景

存储对象数据

购物车

列表-List

数据结构

linkedList

//定义链表节点的结构体 
typedf struct listNode{
    //前一个节点
    struct listNode *prev;
    //后一个节点
    struct listNode *next;
    //当前节点的值的指针
    void *value;
}listNode;

使用双向链表实现,pre指向前一个节点,next指针指向后一个节点,value保存着当前节点对应的数据对象

zipList

typedf struct ziplist<T>{
    //压缩列表占用字符数
    int32 zlbytes;
    //最后一个元素距离起始位置的偏移量,用于快速定位最后一个节点
    int32 zltail_offset;
    //元素个数
    int16 zllength;
    //元素内容
    T[] entries;
    //结束位 0xFF
    int8 zlend;
}ziplist

优点:

1、采用连续内存存储,减少了许多内存碎片和指针的内存占用,进而节约了内存。适合列表对象中元素的长度较小或者数量较少时。

缺点:

1、不利于修改操作,插入和删除操作需要频繁地申请和释放内存。特别是当zipList长度很长时,一次realloc可能会导致大量的数据拷贝。

quickList

qucikList是由zipList和双向链表linkedList组成的混合体。它将linkedList按段切分,单个节点使用zipList来紧凑存储,多个zipList之间使用双向指针串接起来。示意图如下所示:

常用指令

lpush key value value1:将一个或多个数据插入列表头部

rpush key value vlue1:将一个或多个数据插入列表尾部

lpop key:移出并获取列表的第一个元素

rpop key:移出并获取最后一个元素

blpop key timeout:移出并获取第一个元素,如果列表中没有元素会阻塞列表直到指定时间

llen key:列表长度

lindex key index:通过索引获取列表中的元素

场景

1、日志记录,利用lpush插入数据,rpop读取数据模拟mq消息队列异步处理日志数据

2、抽奖、抢票。list是线程安全的,所有pop操作是原子性的,适用于抽奖,抢票等场景,用来防止超卖问题,可以分为以下三步进行:

a,将奖品打散放入redis list中

b,执行pop命令进行抽奖

c,数据库中写入抽奖记录

3、流量削峰,将所有的请求全部放到list中,然后开启多个线程来处理后续请求,减轻服务器压力,用来处理一些高并发场景。

集合-Set

数据结构

其底层有两种实现方式:

1.当value是整数值时,且数据量不大时使用inset来存储,

2.其他情况都是用字典dict来存储

inset的结构:

typedf struct inset{
    uint32_t encoding;//编码方式 有三种 默认 INSET_ENC_INT16
    uint32_t length;//集合元素个数
    int8_t contents[];//实际存储元素的数组 
                      //元素类型并不一定是ini8_t类型,柔性数组不占intset结构体大小,并且数组中的元
                      //素从小到大排列
}inset;

常用命令

命令 描述

sadd key value1 [value2] :向集合添加多个元素,如元素存在则忽略. 如集合key不存在,则新建集合key

scard key:返回集合成员数量

smembers key:返回集合中的所有成员

sismember key member:判断 member 元素是否是集合 key 的成员,是返回1 ,如不是或key不存在返回0

srem key member1 [member2]:移除集合中一个或多个成员,如成员不存在则忽略,如key不存在返回0

spop key [count]:从存储在key的集合中移除并返回一个或多个(count)随机元素

srandmember key [count]:返回集合中一个或多个随机元素

smove source destination member:将member元素从source集合移动到destination集合中,如source中元素不存在返回0,如source中元素存在且destination中也存在,则只删除source中元素

sdiff key1 [key2]:返回给定的第一个集合和其他集合的差集.(即key1中的值,在其他key中找不到)

sdiffstore destination key1 [key2]:返回给定的第一个集合与其他的集合的差集并存储在destination中,如果destination已经存在, 则将其覆盖重写

sinter key1 [key2]:返回所有集合的交集(所有key的值中相同的值)

sunion key1 [key2]:返回所有集合的并集(所有key的值合并去重的值)

场景

1、利用值的唯一性,和集合提供的,对两个集合间的数据进行交集、并集、差集运算的操作,来推荐好友和获取共同好友等

2、利用值的唯一性,可以统计访问网站的所有独立 IP

有序集合-Zset

数据结构

zset在Redis中两种不同的实现,分别是zipList和skipList

常用命令

ZADD key score1 member1 [score2 member2]

向有序集合添加一个或多个成员,或者更新已存在成员的分数

ZCARD key
获取有序集合的成员数

ZCOUNT key min max
计算在有序集合中指定区间分数的成员数

ZINCRBY key increment member
有序集合中对指定成员的分数加上增量 increment

ZINTERSTORE destination numkeys key [key ...]
计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 destination 中

ZLEXCOUNT key min max
在有序集合中计算指定字典区间内成员数量

ZRANGE key start stop [WITHSCORES]
通过索引区间返回有序集合指定区间内的成员

ZSCORE key member
返回有序集中,成员的分数值

场景

1、排行榜

2、延时队列

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言