面试:请介绍下Redis的十大数据类型:
Redis是一个
key-value
的数据库,key一般是String类型,不过value的类型多种多样
:
1.数据类型 -> 字符串(String)类型
1.1.String简介
- 1.String就是
字符串类型
,是Redis最基本的类型, - 2.
一个key对应一个value
,value是字符串
- 3.一个Redis中字符串value
最多
可以是512M
,根据其字符串的格式不同,又可分为3类
:String
:普通字符串int
:整数类型,可以自增、自减操作float
:浮点型,可以自增、自减操作
- 4.不管其value是哪种格式,
底层都是字节数组形式存储,只不过是编码方式不同
; - 5.String类型是
二进制安全的
。意思是:Redis的string可以包含任何数据
。比如jpg图片的二进制编码或者序列化的对象。
1.2.String中的命令
set <key><value>
:添加键值对get <key>
:查询对应键值append <key><value>
:将给定的 追加到原值的末尾strlen <key>
:获得值的长度setnx <key><value>
:只有在 key 不存在时,设置 key 的值incr <key>
:将 key 中储存的数字值增1,只能对数字值操作,如果为空,新增值为1decr <key>
:将 key 中储存的数字值减1, 只能对数字值操作,如果为空,新增值为-1incrby / decrby <key><步长>
:将 key 中储存的数字值增减。自定义步长。mset <key1><value1><key2><value2>
: 同时设置一个或多个 key-value对mget <key1><key2><key3>
:同时获取一个或多个 valuemsetnx <key1><value1><key2><value2>
:同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。getrange <key><起始位置><结束位置>
:获得值的范围,类似java中的substring()setrange <key><起始位置><value>
:用 覆写所储存的字符串值,从<起始位置>开始(索引从0开始)。setex <key><过期时间><value>
:设置键值的同时,设置过期时间,单位秒。getset <key><value>
:以新换旧,设置了新值同时获得旧值。
2.哈希(Hash):
2.1.哈希(Hash)简介
- 1.Hash 是一个
键值对集合
; - 2.Hash是一个string类型的field和value的
映射表
,hash特别适合
用于存储对象
,value是一个无序字典。类似Java里面的Map<String,Object>
- 3.如果用
普通的key/value结构
来存储,主要有以下2种存储方式: - 4.在数据类型1中,存储的数据value结构就如第一种存储结构,
当需要修改对象某个字段时很不方便
:
- 5.如果使用Hash存储,用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,这样就可以针对单个字段做CRUD,存储的数据结构结构如下,
- 6.下面通过
key(用户ID) + field(属性标签)
就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题
2.2.常用命令
- 1.
hset <key><field><value>
:给<key>
集合中的<field>
键赋值 - 2.
hget<key1><field>
:从<key1>
集合<field>
取出 value - 3.
hmset <key1><field1><value1><field2><value2>
:批量设置hash的值 - 4.HMGET:批量获取多个hash类型key的field的值
- 5.HGETALL:获取一个hash类型的key中的所有的field和value
- 6.
hexists<key1><field>
查看哈希表 key 中,给定域 field 是否存在。 - 7.
hkeys <key>
列出该hash集合的所有field - 8.
hvals <key>
列出该hash集合的所有value - 9.
hincrby <key><field><increment>
为哈希表 key 中的域 field 的值加上增量<increment>
- 10.
hsetnx<key><field><value>
将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field (相当于是某个属性)不存在
3.数据类型 -> 列表(List)类型:
3.1. List简介
- 1.
单键多值 Redis 列表
是简单的字符串列表
,按照插入顺序排序。 - 2.可以添加一个元素到列表的头部(左边)或者尾部(右边)。
- 3.它的底层实际是
个双向链表
,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差
。既可以支持正向检索
和也可以支持反向检索
。
- 4.特征也与Java中的LinkedList类似:
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
- 5.常用来
存储一个有序数据
,例如:朋友圈点赞列表,评论列表等
。
3.2.List中常用命令
lpush/rpush <key><value1><value2><value3> ....
从左边/右边插入一个或多个值。lpop/rpop <key>
从左边/右边吐出一个值。值在键在,值光键亡,在没有元素时直接返回nil。BLPOP和BRPOP
:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil
rpoplpush <key1><key2>
从列表右边吐出一个值,插到列表左边。lrange <key><start><stop>
按照索引下标获得元素(从左到右)lrange mylist 0 -1
0左边第一个,-1右边第一个,(0-1表示获取所有)lindex <key><index>
按照索引下标获得元素(从左到右)llen <key>
获得列表长度linsert <key> before <value><newvalue>
在的前面插入插入值lrem <key><n><value>
从左边删除n个value(从左到右)lset<key><index><value>
将列表key下标为index的值替换成value
3.数据类型 -> 集合(Set)类型:
3.1.简介
- 1.set对外提供的功能与list类似,
与Java中的HashSet类似
,可以看做是一个value为null的HashMap。因为也是一个hash表,因此具备与HashSet类似的特征:- 无序
- 元素不可重复
- 查找快
- 支持交集、并集、差集等功能
- 2.是一个
列表
的功能,特殊的地方是:set是可以自动排重
, - 3.当需要存储一个
列表数据
,又不希望出现重复数据时
,就可以选择使用set - 4.
set提供了判断
某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。 - 5.Redis的Set是string类型的
无序集合。它底层其实是一个value为null的hash表
,所以添加、删除、查找的复杂度都是O(1)
。 - 6.一个算法,随着数据的增加,执行时间的长短,如果是O(1),数据增加,查找数据的时间不变
3.2.Set中常用命令
sadd <key><value1><value2>
将一个或多个 member 元素加入到集合 key 中,已经存在的member 元素将被忽略smembers <key>
取出该集合的所有值。sismember<key><value>
判断集合是否为含有该值,有1,没有0scard<key>
返回该集合的元素个数
。srem <key><value1><value2>
:删除集合中某个key中是否具有某个元素。spop <key>
随机从该集合中吐出
一个值。srandmember <key><n>
随机从该集合中取出
n个值。不会从集合中删除
。smove<source><destination>value
把集合中一个值从一个集合移动
到另一个集合sinter<key1><key2>
返回两个集合的交集
元素。sunion <key1><key2>
返回两个集合的并集
元素。sdiff<key1><key2>
返回两个集合的差集
元素(key1中的,不包含key2中的)
5.数据类型 -> 有序集合Zset(sorted set) 类型
5.1.Zset简介
- 1.Redis有序集合zset与普通集合set非常相似,是一个
没有重复元素的字符串集合。
- 2.不同之处是
有序集合的每个成员都关联了一个评分(score)
,这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。 - 3.集合的成
员是唯一
的,但是评分可以是重复了
。 - 4.因为元素是有序的, 所以你也可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。
- 5.访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。
5.2.Zset中常用命令
- 1.
zadd <key><score1><value1><score2><value2>
将一个或多个 member 元素及其 score值加入到有序集 key 当中。 - 2.
zrange <key><start><stop> [WITHSCORES]
返回有序集 key 中,下标在之间的元素,带WITHSCORES,可以让分数一起和值返回到结果集。 - 3.
zrangebyscore key minmax [withscores] [limit offset count]
返回有序集 key 中,所有 score 值介于 min和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。 - 4.
zrevrangebyscore key maxmin [withscores] [limit offset count]
:同上,改为从大到小排列。 - 5.
zincrby <key><increment><value>
为元素的score加上增量 - 6.
zrem <key><value>
:删除该集合下,指定值的元素 - 7.
zcount <key><min><max>
统计该集合,分数区间内的元素个数 - 8.
zrank <key><value>
返回该值在集合中的排名,从0开始。 - 9.
SCARD key
: 返回set中元素的个数 - 10.
SISMEMBER key member
:判断一个元素是否存在于set中 - 11.
SDIFF key1 key2 ...
:求key1与key2的差集 - 12.
SUNION key1 key2 ..
:求key1和key2的并集
6.GEO类型简介:
6.1.简介:
- 1.GEO主要是用于地理位置信息,并对存储的信息进行操作,包括:
- 添加地理位置的坐标
- 获取地理位置的坐标
- 计算两个位置之间的距离
- 根据用户给定的经纬度坐标来获取指定范围内的地理位置集合
7.HyperLogLog类型:
7.1.简介:
- 1.HyperLogLog主要是用于做基数统计的算法,HyperLogLog的优点是:在输入元素的数量或者体积非常非常大的时候,计算基数所需的空间总是固定且很小的
- 2.在redis中,每个HyperLogLog键只需要花费12KB内存,就可以计算2的64次方的不同元素的基数,这和基数计算时,元素越多内存消耗就越多的集合形成鲜明对比
- 3.但因为HyperLogLog只会根据输入元素来计算基数,而不会存储输入元素本身,所以HyperLogLog不能像集合那样,返回输入的各个元素
8.bitmap类型:
9.bitfield位域:
10.Stream类型:
10.1.Stream是什么:
- 1.在Redis5.0之前,其实现消息队列的方案:
- 使用List实现消息队列,List实现方式是点对点的模式
- Pub/Sub
- 2.在5.0之后,出现了Stream,可以使用这种类型来实现Redis版的MQ消息中间件 + 阻塞队列
10.2.能干嘛:
- 1.这个数据类型可以实现消息队列,支持消息的持久化,支持生成全局唯一ID、支持ack确认消息的模式、支持消费组模式等,可以让消息队列更加稳定和可靠
10.3.基本命令:
a.队列相关指令:
b.消费组相关指令:
c.四个特殊符号:
d.指令实操:
d1.队列相关指令:
d1-1.XADD:添加消息到队列末尾:
- 1.XADD 用于向Stream 队列中添加消息,如果指定的Stream 队列不存在,则该命令执行时会新建一个Stream 队列
- 2.
*
号表示服务器自动生成 MessageID(类似mysql里面主键auto_increment),后面顺序跟着一堆 业务key/value
d1-2.XRANGE:用于获取消息列表(可以指定范围),忽略删除的消息
d1-3.XREVRANGE:
与XRANGE的区别在于:获取消息列表元素的方向是相反的,end在前,start在后
d1-4.XDEL:
d1-5.XLEN:
d1-6.XTRIM:用于对Stream的长度进行截取,如超长会进行截取
d1-7.XREAD:用于获取消息(阻塞、非阻塞),只会返回大于指定ID的消息
- 1.非阻塞:
- 2.阻塞:
- 3.小总结: