本博客属作者原创,未经允许禁止转载,请尊重原创!如有问题请联系QQ509961766
Redis 不像传统数据库一样,有table的概念,schema 所对应的db仅以编号区分。同一个db 内,key 作为顶层模型,它的值是扁平化的。也就是说db 就是key的命名空间。
我们都知道,在 redis 中一共有5种数据结构,那每种数据结构的使用场景都是什么呢?
- String-字符串
- Hash-字典
- List-列表
- Set-集合
- Sorted Set-有序集合
下面我们就来简单汇总一下,这个5种类型的常用命令,以及使用场景,在什么情况下使用哪种数据结构。这里只列出的常用命令,后面有章节会详细的介绍各自的命令,对命令不熟悉的同学可以打开客户端跟着练习,这样有助于理解数据类型,也熟悉的常用命令。话不多说,进入正题。
1.String字符串
String 数据结构是最常用的类型,可以说很多人除了String,别的数据类型基本没用过, 跟其他语言中的字符串一样,形如key value,如hello world, hello是key, world是值。value 不仅可以是 String,也可以是数字。总之,string可以存一切内容,什么都能存,只不过要看具体的使用场景。
命令 | 描述 |
---|---|
SET key value | 设置指定 key 的值 |
GET key | 获取指定 key 的值 |
SETNX key value | 只有在 key 不存在时设置 key 的值 |
SETEX key seconds value | 设置key的值 ,并将 key 的过期时间设为 seconds (以秒为单位) |
APPEND key value | 将字符串添加到末尾 |
打开客户端练习一下
举个例子,存key=hello,value=this is a redis test
String的应用场景
1.储存某个字符串,字段
2.储存某个对象
3.计数器,字符串是整数时,可以使用自增,自减,例如id自增,微信点赞自增
4.Redis的所有操作都是单线程保证了数据的原子性,在高并发场景下保证数据的一致性
2.Hash字典
我们经常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值(一般是 JSON 格式),比如用户的昵称、年龄、性别、积分等。这时候在需要修改其中某一项时,通常需要将字符串(JSON)取出来,然后进行反序列化,修改某一项的值,再序列化成字符串(JSON)存储回去。简单修改一个属性就干这么多事情,消耗必定是很大的,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。而 Redis 的 Hash 结构可以使你像在数据库中 Update 一个属性一样只修改某一项属性值。Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
命令 | 描述 |
---|---|
HSET key field value | 将哈希表 key 中的字段 field 的值设为 value |
HMSET key field1 value1 [field2 value2 ] | 同时将多个 field-value (域-值)对设置到哈希表 key 中 |
HMGET key field1 [field2] | 获取所有给定字段的值 |
HKEYS key | 获取所有哈希表中的字段 |
打开客户端练习一下
举个例子,例如我要存科比这个人的姓名,年龄,性别,生日,湖人队等信息
命令就是:HMSET kobe name “bryant” age 42 sex “man” birth “2020-08-23” team “Lakers”
Hash的应用场景
hash 类型十分适合存储对象类数据。
相比于在 String 中介绍的把对象转化为 json 字符串存储,
Hash 的结构可以任意添加或删除‘字段名’,更加高效灵活。
而String中存json对象,如果要修改json中某个属性,开销是很大的。
而Hash类型可以很好的解决这个问题,大大减小开销
3.List列表(有序可重复)
List 是按照插入顺序排序的字符串链表,可以在头部和尾部插入新的元素(redis 使用双端链表实现的 List)。使用 List 结构,我们可以轻松地实现最新消息排行等功能(比如新浪微博的 TimeLine )。List 的另一个应用就是消息队列,可以利用 List 的 *PUSH 操作,将任务存在 List 中,然后工作线程再用 POP 操作将任务取出进行执行。
命令 | 描述 |
---|---|
LPUSH key value1 [value2] | 将一个或多个值插入到列表头部 |
LPUSHX key value | 将一个值插入到已存在的列表头部 |
LRANGE key start stop | 获取列表指定范围内的元素 |
LLEN key | 获取列表长度 |
打开客户端练习一下
举个例子,存科比相关的所有属性到list中
命令是LPUSH player kobe bryant 42 man 1978-08-23 Lakers PG
然后LLEN player可以查看list的长度
然后LRANGE player 0 6 可以根据下标来获取list,注意一定要带下标,否则命令错误。
下标不对不会出错,只不过会获取到空集合,例如start大于end下标
List的应用场景
1.消息队列,list类型的lpop和rpush能实现队列的功能
2.最新消息,list类型的lpush命令和lrange命令能实现最新列表的功能,
每次通过lpush命令往列表里插入新的元素,然后通过lrange命令读取最新的元素列表,
如朋友圈的点赞列表、评论列表。
3.排行榜,list类型的lrange命令可以分页查看队列中的数据。可将每隔一段时间计算一次的排行榜存储在list类型中
4.由于list 是链表结构,所有如果在头部和尾部插入数据,性能会非常高,不受链表长度的影响;
但如果在链表中插入数据,性能就会越来越差。
4.Set集合(无序不可重复)
Set 就是一个集合,集合的概念就是一堆不重复值的组合。利用 Redis 提供的 Set 数据结构,可以存储一些集合性的数据。而且set集合当中元素是没有顺序的,不存在元素下标。比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。因为 Redis 非常人性化的为集合提供了求交集、并集、差集等操作,那么就可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
命令 | 描述 |
---|---|
SADD key member1 [member2] | 向集合添加一个或多个成员 |
SCARD key | 获取集合的长度 |
SISMEMBER key member | 判断 member 元素是否是集合 key 的成员 |
SMEMBERS key | 返回集合中的所有成员 |
SREM key member1 [member2] | 移除集合中一个或多个成员 |
打开客户端练习一下
举个例子,存NBA中球员的名字到set集合中
SADD NBA kobe harden curry james westbrook lillard durant paul irving love anthony embiid
然后查看集合SMEMBERS NBA
然后查看集合长度SCARD NBA
然后判断Jordan是否在集合中
然后删除元素kobe
Set的应用场景
1.共同好友/关注/粉丝/感兴趣/黑名单的人集合,求交集,并集,差集
2.随机集合,由于set是无序集合,适合一些随机使用场景,例如微博推荐,标签等等
5.Sorted Set有序集合
和Set相比,Sorted Sets是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,比如一个存储NBA球员技术统计集合,其集合 value 可以是球员的号码,而 score 就可以是球员的得分,这样在数据插入集合的时候,就已经进行了天然的排序。另外还可以用 Sorted Sets 来做带权重的队列,比如普通消息的 score 为1,重要消息的 score 为2,然后工作线程可以选择按 score 的倒序来获取工作任务。让重要的任务优先执行。
命令 | 描述 |
---|---|
ZADD key score1 member1 [score2 member2] ] | 向有序集合添加一个或多个成员,或者更新已存在成员的分数 |
ZCARD key | 获取集合的长度 |
ZSCORE key member | 返回有序集中,成员的分数值 |
ZRANGE key start stop [WITHSCORES] | 通过索引区间返回有序集合指定区间内的成员 |
打开客户端练习一下
例如存NBA本赛季球员得分榜
ZADD SCORE 33.4 HARDEN 29.1 JAMES 28.8 DURANT 27.7 CURRY 27.1 WESTBROOK 27.1 LILLARD
然后ZCARD SCORE查看长度
然后ZSCORE SCORE JAMES 查看詹姆斯的分数
然后ZRANGE SCORE 0 5查看前6名得分榜
Sorted Set的应用场景
1.好友亲密度
2.NBA球员得分榜