目录
- 一、字符串(String)
- 二、哈希(Hash)
- 三、列表(List)
- 四、集合(Set)
- 五、有序集合(sorted set)
一、字符串(String)
- 类型介绍
字符串类型是Redis中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据。你可以用其存储用户的任何数据、JSON化的对象甚至是一张图片。一个字符串类型键允许存储的数据的最大容量是512MB。
字符串类型是其他4种数据类型的基础,其他数据类型和字符串类型的差别从某种角度来说只是组织字符串的形式不同。 - 字符串常用命令
序号 | 命令及描述 |
1 | SET key value 设置指定 key 的值 |
2 | GET key 获取指定 key 的值。 |
3 | GETRANGE key start end 返回 key 中字符串值的子字符 |
4 | MGET key1 [key2…] 获取所有(一个或多个)给定 key 的值。 |
5 | STRLEN key 返回 key 所储存的字符串值的长度。 |
6 | MSET key value [key value …] 同时设置一个或多个 key-value 对。 |
7 | INCR key 将 key 中储存的数字值增一。 |
8 | INCRBY key increment 将 key 所储存的值加上给定的增量值(increment) 。 |
9 | INCRBYFLOAT key increment 将 key 所储存的值加上给定的浮点增量值(increment) 。 |
10 | DECR key 将 key 中储存的数字值减一。 |
11 | DECRBY key decrement key 所储存的值减去给定的减量值(decrement) 。 |
12 | APPEND key value 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。 |
- 应用场景
- 用于缓存;比如缓存动态生成的页面;缓存热数据;缓存计算复杂的结果数据;缓存json化的对象;缓存base_64的编码的图片等;
一般我们缓存数据的时候都会有这么两个步骤:
1、获取数据时,先去读Redis,如果没有数据,读取数据库,然后将数据写入到Redis。
2、插入数据后,同时写入Redis。
- 计数器/id分发器;比如记录网站每日PV;记录关注、被关注的人数;记录阅读量;记录点赞的数量;记录某个文件的下载数量;记录视频、音频被播放的次数;记录产品销量;记录数据库的主键id等
在开发中经常会遇到计数的功能,这时我们可以使用INCR 、DECR 、INCRBY、DECRBY等Redis 命令对数据进行增减;需要注意的是Redis的自增是有范围的,它的范围是 - 2^63-1 ~ 2^63-1,超过了这个值,Redis 会报错。
- 限时服务;比如短信、邮箱验证需要的验证码;限制用户每分钟访问的次数;限时优惠活动等;
一般在登录、注册、找回密码等功能都会通过手机、邮箱获取验证码登录,我们要保证前后端的验证码一致,且不会被懂行的人越过前端验证,可以缓存到Redis中,并设置相应的过期时间;有些爬虫很恶心,会不考虑你网站的情况下疯狂获取你网站的数据,基本相当于弱一些的DDOS,为了防止这种情况,避免网站卡顿,影响其他用户,可以使用Redis可以对键值设置过期时间
- 共享session
如果我们项目里采用了session,那我们做服务器集群的时候,随着用户访问到不同的服务器,就会在每个从服务器上都各自存储自己的session,那么当用户第一次请求被分发给A服务器,第二次被分发给B服务器的时候,session信息会由于不共享而导致用户需要重新登录或者其他一些操作,我们不得不考虑第三应用来存储session。通过我们用关系型数据库或Redis等非关系型数据库来共享session。又因为关系型数据库存储和读取性能远远无法跟Redis等非关系型数据库,所以Redis是最好的选择。
- 分布式锁
使用setnx实现分布式锁。例如,我们在项目中有时会加一些定时任务在后台跑功能,为了保证定时任务的高可用,往往会同时部署多个具备相同功能的定时任务,但是业务上只希望其中的某一台服务执行定时任务,当定时任务的时间点触发时,多个服务同时竞争一个锁,获取到锁的执行定时任务,没获取到的放弃执行定时任务。
- 位图
比如我们要记录用户每月或者每年的在线天数,这时如果将记录存储在数据库中,等用户量上来后悔占用很多磁盘空间,而且效率也不高。这时候使用位图每一比特可以记录一天的登录情况,一字节可以记录八天的情况,这样的话一个用户一年也用不了多少内存空间。
二、哈希(Hash)
- 类型介绍
Redis是采用字典结构以键值对的形式存储数据的,而Hash的键值也是一种字典结构,其存储了字段和字段值的映射,但字段值只能是字符串,不支持其他数据类型,换句话说,散列类型不能嵌套其他的数据类型。
注意:
Redis 中每个 Hash 可以存储 2^32 - 1 个键值对(40多亿)。
Redis Hash 超时时间只能设置在 Hash key 上,不能单独对Hash里面的键值对设置过期时间。
Redis的其他数据类型同样不支持数据类型嵌套。比如集合类型的每个元素都只能是字符串,不能是另一个集合或散列表等。 - 常用命令
序号 | 命令及描述 |
1 | [HDEL key field2 [field2…]] 删除一个或多个哈希表字段 |
2 | [HEXISTS key field] 查看哈希表 key 中,指定的字段是否存在。 |
3 | [HGET key field] 获取存储在哈希表中指定字段的值 |
4 | [HGETALL key] 获取在哈希表中指定 key 的所有字段和值 |
5 | [HINCRBY key field increment] 为哈希表 key 中的指定字段的整数值加上增量 increment |
6 | [HINCRBYFLOAT key field increment] 为哈希表 key 中的指定字段的浮点数值加上增量 increment 。 |
7 | [HKEYS key] 获取所有哈希表中的字段 |
8 | [HLEN key] 获取哈希表中字段的数量 |
9 | [HMGET key field1 [field2]] 获取所有给定字段的值 |
10 | [HMSET key field1 value1 [field2 value2 ]] 同时将多个 field-value (域-值)对设置到哈希表 key 中。 |
11 | [HSET key field value] 将哈希表 key 中的字段 field 的值设为 value 。 |
12 | [HSETNX key field value] 只有在字段 field 不存在时,设置哈希表字段的值。 |
13 | [HVALS key] 获取哈希表中所有值 |
14 | HSCAN key cursor [MATCH pattern] [COUNT count] 迭代哈希表中的键值对。 |
- 应用场景
- 缓存对象
Hash特别适合用于存储对象,而且取数据的时候时间复杂度为 O(1)。
- 购物车
以用户id为key,商品id为field,商品数量为value;通过HINCRBY增减商品数量;通过HDEL移除商品;通过HLEN 获取商品的总量;通过HGETALL 全选商品;通过HGET 、HMGET 获取一个或者多个选中的商品;
给Redis键值命名时最好能见名知意,例如:shoppingcart_user:id=>commodity:id=>商品数量
- id分发器
项目中总有些关联表,在插入时必须先获得A表的主键id才能插入B表的数据;亦或者批量插入时需要提前给每一条数据设置主键id;这时当我们把数据库表名作为hash的field,把主键id设为value, 再配合HINCRBY命令就可以在插入数据时,提前获得主键id
三、列表(List)
- 类型介绍
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边),还可以获取指定范围的元素列表、获取指定索引下标的元素等。列表类型内部是使用链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。不过使用链表的代价是通过索引访问元素比较慢。
注意:
每个列表最多可以存储 2^32 - 1 个元素(40多亿) - 常用命令
序号 | 命令及描述 |
1 | [BLPOP key1 [key2 ] timeout] 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
2 | [BRPOP key1 [key2 ] timeout] 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
3 | [BRPOPLPUSH source destination timeout] 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
4 | [LINDEX key index] 通过索引获取列表中的元素 |
5 | [LINSERT key BEFORE|AFTER pivot value]在列表的元素前或者后插入元素 |
6 | [LLEN key] 获取列表长度 |
7 | [LPOP key] 移出并获取列表的第一个元素 |
8 | [LPUSH key value1 [value2]] 将一个或多个值插入到列表头部 |
9 | [LPUSHX key value] 将一个或多个值插入到已存在的列表头部 |
10 | [LRANGE key start stop] 获取列表指定范围内的元素 |
11 | [LREM key count value] 移除列表元素 |
12 | [LSET key index value] 通过索引设置列表元素的值 |
13 | [LTRIM key start stop] 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 |
14 | [RPOP key] 移除并获取列表最后一个元素 |
15 | [RPOPLPUSH source destination] 移除列表的最后一个元素,并将该元素添加到另一个列表并返回 |
16 | [RPUSH key value1 [value2]] 在列表中添加一个或多个值 |
17 | [RPUSHX key value] 为已存在的列表添加值 |
- 应用场景
- 排行榜
虽然list能够实现排行榜,但是局限的地方在于list不能实现微博热搜排行榜或者百度搜索热点排行榜那种实时动态变化的排行榜,只能实现那种经过计算后存到list中的排行榜,比如学生成绩排行榜。实现排行榜要点在于使用list类型的lrange命令,该可以分页查看队列中的数据。
- 最新文章、消息等
list类型的lpush命令和lrange命令能实现最新列表的功能,每次通过lpush命令往列表里插入新的元素,然后通过lrange命令读取最新的元素列表,如朋友圈的点赞列表、评论列表。但是,并不是所有的最新列表都能用list类型实现,因为对于频繁更新的列表,list类型的分页可能导致列表元素重复或漏掉。
- 任务队列
list类型的lpop和rpush(或者反过来,lpush和rpop)能实现队列的功能。
- 优先级队列
list类型的lpush和brpop可以通过阻塞队列实现不同队列的优先级,例如项目中需要给新用户发邮件;用户订阅文章栏目后,每次更新文章也需要给用户发邮件;
- 秒杀
可以根据商品的库存数量初始化一个一定长度的列表,然后每卖出一个就pop一个,直到列表为空,秒杀结束。
四、集合(Set)
- 类型介绍
集合的概念高中的数学课就学习过。而Redis集合是string的无序集合。集合成员是唯一的,即集合中不能出现重复的数据。一个集合类型可以存储至多2^32-1个字符串。 - 常用命令
序号 | 命令及描述 |
1 | [SADD key member1 [member2]] 向集合添加一个或多个成员 |
2 | [SCARD key] 获取集合的成员数 |
3 | [SDIFF key1 [key2]] 返回给定所有集合的差集 |
4 | [SDIFFSTORE destination key1 [key2]] 返回给定所有集合的差集并存储在 destination 中 |
5 | [SINTER key1 [key2]] 返回给定所有集合的交集 |
6 | [SINTERSTORE destination key1 [key2]] 返回给定所有集合的交集并存储在 destination 中 |
7 | [SISMEMBER key member] 判断 member 元素是否是集合 key 的成员 |
8 | [SMEMBERS key]返回集合中的所有成员 |
9 | [SMOVE source destination member] 将 member 元素从 source 集合移动到 destination 集合 |
10 | [SPOP key] 移除并返回集合中的一个随机元素 |
11 | [SRANDMEMBER key [count]] 返回集合中一个或多个随机数 |
12 | [SREM key member1 [member2]] 移除集合中一个或多个成员 |
13 | [SUNION key1 [key2]] 返回所有给定集合的并集 |
14 | [SUNIONSTORE destination key1 [key2]] 所有给定集合的并集存储在 destination 集合中 |
15 | [SSCAN key cursor [MATCH pattern] [COUNT count]]迭代集合中的元素 |
- 应用场景
- 好友/共同好友/可能认识的人/关注/粉丝
SINTER 命令可以获得A和B两个用户的共同好友
SISMEMBER 命令可以判断A是否是B的好友
SCARD 命令可以获取好友数量
关注时,SMOVE 命令可以将B从A的粉丝集合转移到A的好友集合
SDIFF 命令可以获取A和B可能认识的人
- 黑名单/白名单
经常有业务出于安全性方面的考虑,需要设置用户黑名单、ip黑名单、设备黑名单等,set类型适合存储这些黑名单数据,SISMEMBER 命令可用于判断用户、ip、设备是否处于黑名单之中。
- 随机展示
通常,首页的展示区域有限,但是又不能总是展示固定的内容,一种做法是先确定一批需要展示的内容,再从中随机获取。
- 抽奖
点击参与抽奖的时候,将对应用户加到抽奖集合中,通过SMEMBERS 抽奖活动ID 获取参与人数,通过SRANDMEMBER 抽奖活动ID或SPOP 抽奖活动ID 进行抽奖。 这样的设计比用程序方便多,但是如果奖品比较多,又或者需要自定义不同奖品的权重就需要自己设计抽奖程序了。
- 标签
比如我们在CSDN发布博客是需要选择文章标签的,然后给一篇博客打上标签之后,就可以通过标签进行分类展示、进行搜索;亦或者一个电子商务的网站会对不同标签的用户做不同类型的推荐,比如对数码产品比较感兴趣的人,在各个页面或者通过邮件的形式给他们推荐最新的数码产品,通常会为网站带来更多的利益。
- 统计网站每日的UV
利用集合元素的唯一性,可以记录访问网站的所有独立 IP,用于统计UV
五、有序集合(sorted set)
- 类型介绍
有序集合在集合类型的基础上有序集合类型为集合中的每个元素都关联了一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在等集合类型支持的操作,还能够获得分数最高(或最低)的前N个元素、获得指定分数范围内的元素等与分数有关的操作。虽然集合中每个元素都是不同的,但是它们的分数却可以相同。
有序集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。 - 常用命令
序号 | 命令及描述 |
1 | [ZADD key score1 member1 [score2 member2]] 向有序集合添加一个或多个成员,或者更新已存在成员的分数 |
2 | [ZCARD key] 获取有序集合的成员数 |
3 | [ZCOUNT key min max] 计算在有序集合中指定区间分数的成员数 |
4 | [ZINCRBY key increment member] 有序集合中对指定成员的分数加上增量 increment |
5 | [ZINTERSTORE destination numkeys key [key …]] 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中 |
6 | [ZLEXCOUNT key min max] 在有序集合中计算指定字典区间内成员数量 |
7 | [ZRANGE key start stop [WITHSCORES]] 通过索引区间返回有序集合成指定区间内的成员 |
8 | [ZRANGEBYLEX key min max [LIMIT offset count]] 通过字典区间返回有序集合的成员 |
9 | [ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT]] 通过分数返回有序集合指定区间内的成员 |
10 | [ZRANK key member] 返回有序集合中指定成员的索引 |
11 | [ZREM key member [member …]] 移除有序集合中的一个或多个成员 |
12 | [ZREMRANGEBYLEX key min max] 移除有序集合中给定的字典区间的所有成员 |
13 | [ZREMRANGEBYRANK key start stop] 移除有序集合中给定的排名区间的所有成员 |
14 | [ZREMRANGEBYSCORE key min max] 移除有序集合中给定的分数区间的所有成员 |
15 | [ZREVRANGE key start stop [WITHSCORES]] 返回有序集中指定区间内的成员,通过索引,分数从高到底 |
16 | [ZREVRANGEBYSCORE key max min [WITHSCORES]] 返回有序集中指定分数区间内的成员,分数从高到低排序 |
17 | [ZREVRANK key member] 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序 |
18 | [ZSCORE key member] 返回有序集中,成员的分数值 |
19 | [ZUNIONSTORE destination numkeys key [key …]] 计算给定的一个或多个有序集的并集,并存储在新的 key 中 |
20 | [ZSCAN key cursor [MATCH pattern] [COUNT count]] 迭代有序集合中的元素(包括元素成员和元素分值) |
- 应用场景
- 排行榜
带有权重的排行榜,比如一个游戏的用户得分排行榜
根据好友的“亲密度”排序显示好友列表
根据文章的阅读量或点赞量对文章列表排序