900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Redis数据类型以及应用场景

Redis数据类型以及应用场景

时间:2023-02-01 04:11:01

相关推荐

Redis数据类型以及应用场景

文章目录

前言Redis数据类型String应用场景命令 Hash应用场景命令 List应用场景命令 Set应用场景命令 zset应用场景命令 Bitmap应用场景命令 HyperLogLog应用场景命令 Geospatial应用场景命令 参考

前言

本篇文章主要参考《进大厂系列》系列-Redis常见面试题(带答案),记录redis的相关内容。

Redis数据类型

Redis支持5种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)等,还有一些高级的Redis数据类型,如HyperLogLog、Bitmap等。这些数据类型在底层都是使用redisObject来进行表示。redisObject中有三个重要的属性,分别是type、 encoding 和 ptr。

type表示保存的value的类型。通常有以下几种,也就是常见的五种数据结构:

字符串 REDIS_STRING列表 REDIS_LIST集合 REDIS_SET有序集合 REDIS_ZSET字典 REDIS_HASH

encoding表示保存的value的编码,通常有以下几种:

#define REDIS_ENCODING_RAW 0 // 编码为字符串#define REDIS_ENCODING_INT 1 // 编码为整数#define REDIS_ENCODING_HT 2 // 编码为哈希表#define REDIS_ENCODING_ZIPMAP 3 // 编码为 zipmap#define REDIS_ENCODING_LINKEDLIST 4// 编码为双端链表#define REDIS_ENCODING_ZIPLIST 5 // 编码为压缩列表#define REDIS_ENCODING_INTSET 6 // 编码为整数集合#define REDIS_ENCODING_SKIPLIST 7 // 编码为跳跃表

String

String是简单的 key-value 键值对,value 不仅可以是 String,也可以是数字。String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。

struct sdshdr{int len;/*字符串长度*/int free;/*未使用的字节长度*/char buf[];/*保存字符串的字节数组*/}

应用场景

缓存功能:String字符串是最常用的数据类型,不仅仅是Redis,各个语言都是最基本类型,因此,利用Redis作为缓存,配合其它数据库作为存储层,利用Redis支持高并发的特点,可以大大加快系统的读写速度、以及降低后端数据库的压力。计数器:许多系统都会使用Redis作为系统的实时计数器,可以快速实现计数和查询的功能。而且最终的数据结果可以按照特定的时间落地到数据库或者其它存储介质当中进行永久保存。共享用户Session:用户重新刷新一次界面,可能需要访问一下数据进行重新登录,或者访问页面缓存Cookie,但是可以利用Redis将用户的Session集中管理,在这种模式只需要保证Redis的高可用,每次用户Session的更新和获取都可以快速完成。大大提高效率。

命令

SET key value设置key=valueGET key或者键key对应的值GETRANGE key start end得到字符串的子字符串存放在一个键GETSET key value 设置键的字符串值,并返回旧值GETBIT key offset返回存储在键位值的字符串值的偏移MGET key1 [key2..]得到所有的给定键的值SETBIT key offset value设置或清除该位在存储在键的字符串值偏移SETEX key seconds value键到期时设置值SETNX key value设置键的值,只有当该键不存在SETRANGE key offset value覆盖字符串的一部分从指定键的偏移STRLEN key得到存储在键的值的长度MSET key value [key value...]设置多个键和多个值MSETNX key value [key value...]设置多个键多个值,只有在当没有按键的存在时PSETEX key milliseconds value设置键的毫秒值和到期时间INCR key增加键的整数值一次INCRBY key increment由给定的数量递增键的整数值INCRBYFLOAT key increment由给定的数量递增键的浮点值DECR key递减键一次的整数值DECRBY key decrement由给定数目递减键的整数值APPEND key value追加值到一个键---------------------------------------------------------------------------------------------DEL key如果存在删除键DUMP key返回存储在指定键的值的序列化版本EXISTS key此命令检查该键是否存在EXPIRE key seconds指定键的过期时间EXPIREAT key timestamp指定的键过期时间。在这里,时间是在Unix时间戳格式PEXPIRE key milliseconds设置键以毫秒为单位到期PEXPIREAT key milliseconds-timestamp设置键在Unix时间戳指定为毫秒到期KEYS pattern查找与指定模式匹配的所有键MOVE key db移动键到另一个数据库PERSIST key移除过期的键PTTL key以毫秒为单位获取剩余时间的到期键。TTL key获取键到期的剩余时间。RANDOMKEY从Redis返回随机键RENAME key newkey更改键的名称RENAMENX key newkey重命名键,如果新的键不存在TYPE key返回存储在键的数据类型的值。

Hash

这个是类似 Map 的一种结构,这个一般就是可以将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对象)给缓存在 Redis 里,然后每次读写缓存的时候,可以就操作 Hash 里的某个字段。但是这个的场景其实还是多少单一了一些,因为现在很多对象都是比较复杂的,比如你的商品对象可能里面就包含了很多属性,其中也有对象。

typedf struct dict{dictType *type;//类型特定函数,包括一些自定义函数,这些函数使得key和value能够存储void *private;//私有数据dictht ht[2];//两张hash表 int rehashidx;//rehash索引,字典没有进行rehash时,此值为-1unsigned long iterators; //正在迭代的迭代器数量}dict;typedef struct dictht{//哈希表数组dictEntry **table;//哈希表大小unsigned long size;//哈希表大小掩码,用于计算索引值//总是等于 size-1unsigned 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;

应用场景

假设有多个用户及对应的用户信息,可以用来存储以用户ID为key,将用户信息序列化为比如json格式做为value进行保存。

命令

HDELHDEL key field[field...] 删除对象的一个或几个属性域,不存在的属性将被忽略HEXISTSHEXISTS key field 查看对象是否存在该属性域HGETHGET key field 获取对象中该field属性域的值HGETALLHGETALL key 获取对象的所有属性域和值HINCRBYHINCRBY key field value 将该对象中指定域的值增加给定的value,原子自增操作,只能是integer的属性值可以使用HINCRBYFLOATHINCRBYFLOAT key field increment 将该对象中指定域的值增加给定的浮点数HKEYSHKEYS key 获取对象的所有属性字段HVALSHVALS key 获取对象的所有属性值HLENHLEN key 获取对象的所有属性字段的总数HMGETHMGET key field[field...] 获取对象的一个或多个指定字段的值HSETHSET key field value 设置对象指定字段的值HMSETHMSET key field value [field value ...] 同时设置对象中一个或多个字段的值HSETNXHSETNX key field value 只在对象不存在指定的字段时才设置字段的值HSTRLENHSTRLEN key field 返回对象指定field的value的字符串长度,如果该对象或者field不存在,返回0.HSCANHSCAN key cursor [MATCH pattern] [COUNT count] 类似SCAN命令

List

List列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。List可以简单认为是链表或队列。

typedef struct listNode {struct listNode *prev;struct listNode *next;void *value;} listNode;typedef struct listIter {listNode *next;int direction;} listIter;typedef struct list {listNode *head;listNode *tail;void *(*dup)(void *ptr);void (*free)(void *ptr);int (*match)(void *ptr, void *key);unsigned long len;} list;

应用场景

比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现。类似微博那种下拉不断分页等分页展示的功能简单的消息队列

命令

BLPOPBLPOP key1 [key2 ] timeout 取出并获取列表中的第一个元素,或阻塞,直到有可用BRPOPBRPOP key1 [key2 ] timeout 取出并获取列表中的最后一个元素,或阻塞,直到有可用BRPOPLPUSHBRPOPLPUSH source destination timeout 从列表中弹出一个值,它推到另一个列表并返回它;或阻塞,直到有可用LINDEXLINDEX key index 从一个列表其索引获取对应的元素LINSERTLINSERT key BEFORE|AFTER pivot value 在列表中的其他元素之后或之前插入一个元素LLENLLEN key 获取列表的长度LPOPLPOP key 获取并取出列表中的第一个元素LPUSHLPUSH key value1 [value2] 在前面加上一个或多个值的列表LPUSHXLPUSHX key value 在前面加上一个值列表,仅当列表中存在LRANGELRANGE key start stop 从一个列表获取各种元素LREMLREM key count value 从列表中删除元素LSETLSET key index value 在列表中的索引设置一个元素的值LTRIMLTRIM key start stop 修剪列表到指定的范围内RPOPRPOP key 取出并获取列表中的最后一个元素RPOPLPUSHRPOPLPUSH source destination 删除最后一个元素的列表,将其附加到另一个列表并返回它RPUSHRPUSH key value1 [value2] 添加一个或多个值到列表RPUSHXRPUSHX key value 添加一个值列表,仅当列表中存在

Set

Set理解为一堆值不重复的列表,类似数学领域中的集合概念,且Redis也提供了针对集合的求交集、并集、差集等操作。set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。

Set底层编码有两种,分别是intset和hashtable。如果value可以转成整数值,并且长度不超过512的话就使用intset存储,否则采用hashtable。

typedef struct intset{uint32_t encoding;//编码方式uint32_t length;//集合包含的元素数量int8_t contents[];//保存元素的数组}intset;

应用场景

Set的应用场景可以理解为Set之间的交集、并集以及差集操作。如微博的共同好友,通过求两个用户好友Set的交集得到。

命令

SADDSADD key member [member ...] 添加一个或者多个元素到集合(set)里SACRDSCARD key 获取集合里面的元素数量SDIFFSDIFF key [key ...] 获得队列不存在的元素SDIFFSTORESDIFFSTORE destination key [key ...] 获得队列不存在的元素,并存储在一个关键的结果集SINTERSINTER key [key ...] 获得两个集合的交集SINTERSTORESINTERSTORE destination key [key ...] 获得两个集合的交集,并存储在一个集合中SISMEMBERSISMEMBER key member 确定一个给定的值是一个集合的成员SMEMBERSSMEMBERS key 获取集合里面的所有keySMOVESMOVE source destination member 移动集合里面的一个key到另一个集合SPOPSPOP key [count] 获取并删除一个集合里面的元素SRANDMEMBERSRANDMEMBER key [count] 从集合里面随机获取一个元素SREMSREM key member [member ...] 从集合里删除一个或多个元素,不存在的元素会被忽略SUNIONSUNION key [key ...] 添加多个set元素SUNIONSTORESUNIONSTORE destination key [key ...] 合并set元素,并将结果存入新的set里面SSCANSSCAN key cursor [MATCH pattern] [COUNT count] 迭代set里面的元素

zset

zset是排序的Set。zset添加、删除和测试的时间复杂度均为O(1)(固定时间,无论里面包含的元素集合的数量)。列表的最大长度为 2 32 − 1 2^{32}- 1 232−1元素。zset的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

zset的编码有两种,分别是:ziplist、skiplist。当zset的长度小于 128,并且所有元素的长度都小于 64 字节时,使用ziplist存储;否则使用 skiplist 存储。

应用场景

微博的热搜榜权重消息队列。比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务,让重要的任务优先执行。

命令

ZADDZADD key score1 member1 [score2 member2] 添加一个或多个成员到有序集合,或者如果它已经存在更新其分数ZCARDZCARD key 得到的有序集合成员的数量ZCOUNTZCOUNT key min max 计算一个有序集合成员与给定值范围内的分数ZINCRBYZINCRBY key increment member 在有序集合增加成员的分数ZINTERSTOREZINTERSTORE destination numkeys key [key ...] 多重交叉排序集合,并存储生成一个新的键有序集合。ZLEXCOUNTZLEXCOUNT key min max 计算一个给定的字典范围之间的有序集合成员的数量ZRANGEZRANGE key start stop [WITHSCORES] 由索引返回一个成员范围的有序集合(从低到高)ZRANGEBYLEXZRANGEBYLEX key min max [LIMIT offset count]返回一个成员范围的有序集合(由字典范围)ZRANGEBYSCOREZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] 返回有序集key中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员,有序集成员按 score 值递增(从小到大)次序排列ZRANKZRANK key member 确定成员的索引中有序集合ZREMZREM key member [member ...] 从有序集合中删除一个或多个成员,不存在的成员将被忽略ZREMRANGEBYLEXZREMRANGEBYLEX key min max 删除所有成员在给定的字典范围之间的有序集合ZREMRANGEBYRANKZREMRANGEBYRANK key start stop 在给定的索引之内删除所有成员的有序集合ZREMRANGEBYSCOREZREMRANGEBYSCORE key min max 在给定的分数之内删除所有成员的有序集合ZREVRANGEZREVRANGE key start stop [WITHSCORES] 返回一个成员范围的有序集合,通过索引,以分数排序,从高分到低分ZREVRANGEBYSCOREZREVRANGEBYSCORE key max min [WITHSCORES] 返回一个成员范围的有序集合,以socre排序从高到低ZREVRANKZREVRANK key member 确定一个有序集合成员的索引,以分数排序,从高分到低分ZSCOREZSCORE key member 获取给定成员相关联的分数在一个有序集合ZUNIONSTOREZUNIONSTORE destination numkeys key [key ...] 添加多个集排序,所得排序集合存储在一个新的键ZSCANZSCAN key cursor [MATCH pattern] [COUNT count] 增量迭代排序元素集和相关的分数

Bitmap

位图是支持按 bit 位来存储信息,可以用来实现 布隆过滤器(BloomFilter)。Bitmap 的底层数据结构用的是 String 类型的 SDS 数据结构来保存位数组,Redis 把每个字节数组的 8 个 bit 位利用起来,每个 bit 位 表示一个元素的二值状态(不是 0 就是 1)。

应用场景

用户签到统计活跃用户两亿用户最近 7 天的签到情况,统计 7 天内连续签到的用户总数。

命令

SETBIT <key> <offset> <value>GETBIT <key> <offset>

可参考:Redis 实战篇:巧用 Bitmap 实现亿级数据统计

HyperLogLog

供不精确的去重计数功能,比较适合用来做大规模数据的去重统计,例如统计 UV;

struct hllhdr {char magic[4];/* "HYLL",对应源码注释中的HYLL*/uint8_t encoding; /* HLL_DENSE or HLL_SPARSE.稀疏/密集存储结构标记,对应源码注释中的E */uint8_t notused[3]; /* 保留3字节备用,目前未使用,值为0,对应源码注释中的N/U */uint8_t card[8]; /* Cached cardinality(基数缓存), little endian. 对应源码注释中的Cardin,cardinality<基数> */uint8_t registers[]; /* Data bytes. */};

应用场景

统计注册 IP 数统计每日访问 IP 数统计页面实时 UV 数统计在线用户数统计用户每天搜索不同词条的个数

命令

PFADD key element PFCOUNT key PFMERGE destkey sourcekey

Geospatial

可以用来保存地理位置,并作位置距离计算或者根据半径计算位置等。

应用场景

记录地理位置,计算距离以及附近的人。

命令

geoadd:添加地理位置的坐标。geopos:获取地理位置的坐标。geodist:计算两个位置之间的距离。georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。geohash:返回一个或多个位置对象的 geohash 值。

参考

《Redis设计与实现》《进大厂系列》系列-Redis常见面试题(带答案)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。