Redis数据类型
Redis 数据类型
Redis 支持五种基本类型:String(字符串),Hash(哈希),List(列表),Set(集合)及**SortedSet(zset:有序集合)**。
其他特殊类型有 GEO(主要用于存储地理位置信息),BitMap(位图),HyperLogLog(用来做基数统计的算法)。
Redis 数据结构介绍
Redis 将操作不同数据类型的命令做了分组,官网(https://redis.io/commands)可以查看命令。
| 类型 | 简介 | 特性 | 场景 |
|---|---|---|---|
| String(字符串) | 二进制安全 | 可以包含任何数据,比如jpg图片或者序列化的对象,一个键最大能存储512M | — |
| Hash(字典) | 键值对集合,即编程语言中的Map类型 | 适合存储对象,并且可以像数据库中update一个属性一样只修改某一项属性值(Memcached中需要取出整个字符串反序列化成对象修改完再序列化存回去) | 存储、读取、修改用户属性 |
| List(列表) | 链表(双向链表) | 增删快,提供了操作某一段元素的API | 1,最新消息排行等功能(比如朋友圈的时间线) 2,消息队列 |
| Set(集合) | 哈希表实现,元素不重复 | 1、添加、删除,查找的复杂度都是O(1); 2、为集合提供了求交集、并集、差集等操作 | 1、共同好友 2、利用唯一性,统计访问网站的所有独立ip 3、好友推荐时,根据tag求交集,大于某个阈值就可以推荐 |
| Sorted Set(有序集合) | 将Set中的元素增加一个权重参数score,元素按score有序排列 | 数据插入集合时,已经进行天然排序 | 1、排行榜 2、带权重的消息队列 |
Redis 通用命令
通用命令是部分数据类型的,都可以使用的命令,常见的有:
KEYS:查看符合模板的所有 key(不建议在生产环境设备上使用,如果数据量较大,会阻塞所有请求)。DEL:删除指定的 key(可跟多个key批量删除)EXISTS:判断 key 是否存在EXPIRE:给一个 key 设置有效期,有效期到期时该 key 会被自动删除TTL:查看一个 key 的剩余有效期(-2已过期,-1永久有效)
通过 help [command] 可以查看一个命令的具体用法
String 类型
String 类型,是 Redis 中最简单的存储类型。
其 value 是字符串,不过根据字符串的格式不同,又可以分为3类:
- string:普通字符串
- int:整数类型,可以做自增、自减操作
- float:浮点类型,可以做自增、自 减操作
不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型的最大空间不能超过512m。
String 常用命令
| 序号 | 命令 | 描述 |
|---|---|---|
| 1 | SET key value | 设置指定 key 的值。 |
| 2 | GET key | 获取指定 key 的值。 |
| 3 | MSET key value [key value …] | 同时设置一个或多个 key-value 对。 |
| 4 | MGET key1 [key2..] | 获取所有(一个或多个)给定 key 的值。 |
| 5 | SETEX key seconds value | 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。 |
| 6 | SETNX key value | 只有在 key 不存在时设置 key 的值。 |
| 7 | INCR key | 将 key 中储存的数字值自增1。 |
| 8 | INCRBY key increment | 将 key 所储存的值自增并指定步长 ,如:incrby num 2 让num自增2 |
| 9 | DECR key | 将 key 中储存的数字值减一。 |
| 10 | APPEND key value | 如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。 |
key 层级格式
Redis 没有类似 MySQL 中的 Table 的概念,如何区分不同类型的 key 呢?比如用户 id 和商品 id ?
- Redis 的 key 允许有多个单词形成层级结构,多个单词之间用
:分隔,格式如:项目名:业务名:类型:id
例,假设项目名为 kingshit,有 user 和 product 两种不同类型的数据,可以这样定义key:
- user 相关的 key:
kingshit:user:1 - product 相关的 key:
kingshit:product:1
对象存储
如果 value 是一个 Java 对象,则可以将对象序列化为 JSON 字符串后存储:
| KEY | VALUE |
|---|---|
| kingshit:user:1 | {“id”: 1, “name”: “rwj”, “age”: 28} |
| kingshit:product:1 | {“id”: 1, “name”: “Redmi K50 Ultra”, “price”: 3000} |
使用场景
存储单个值,如用户信息、计数器等。
Hash 类型
Redis Hash 类型,也叫散列,其 value 是一个无序字典,类似于 Java 中的 HashMap 结构。
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿),特别适合用于存储对象(上文将对象序列化为JSON方式存储不方便修改某个字段)。
对象存储(better)
Hash结构:可以将对象中的每个字段独立存储,可针对单个字段做CRUD:
| KEY | VALUE | |
|---|---|---|
| field | value | |
| kingshit:user:1 | name | rwj |
| age | 28 | |
| kingshit:user:2 | name | niu |
| age | 27 |
Hash 常用命令
| 序号 | 命令 | 描述 |
|---|---|---|
| 1 | HSET key field value | 将哈希表 key 中的字段 field 的值设为 value 。 |
| 2 | HGET key field | 获取存储在哈希表中指定字段的值。 |
| 3 | HGETALL key | 获取在哈希表中指定 key 的所有字段和值 |
| 4 | HKEYS key | 获取一个hash类型的key中所有的field |
| 5 | HVALS key | 获取一个hash类型的key中所有的value |
| 6 | HINCRBY key field increment | 为哈希表 key 中的指定字段的整数值自增并指定步长。 |
| 7 | HSETNX key field value | 只有在字段 field 不存在时,设置哈希表字段的值。 |
使用场景
存储对象的字段和值,如存储用户对象、文章对象等。
List 类型
Redis 中的是简单的字符串列表,按照插入顺序排序。支持正向和反向检索。
常用来存储一个有序数据,例如:评论列表、点赞列表等。
类似 Java 的 LinkedList。
特征:
- 有序
- 元素可以重复
- 插入和删除速度快
- 查询速度一般
List 常用命令
| 序号 | 命令 | 描述 |
|---|---|---|
| 1 | LPUSH key value1 [value2]RPUSH key value1 [value2] | 将一个或多个值插入到列表头部将一个或多个值添加到列表尾部 |
| 2 | LPOP keyRPOP key | 移出并获取列表的第一个元素,没有则返回nil移出并获取列表的最后一个元素,没有则返回nil |
| 3 | LRANGE key start stop | 获取列表指定范围内的元素 |
| 4 | BLPOP key1 [key2 ] timeoutBRPOP key1 [key2 ] timeout | 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
思考:
利用 LIst 结构模拟一个栈
- 入口和出口在同一侧(L或者R),存取数据用LPUSH+LPOP结合(或都是R)
利用 List 结构模拟一个队列
- 入口和出口在不同侧,存取数据用首尾结合方式(LPUSH+RPOP)(或RL)
利用 List 结构模拟一个阻塞队列
- 入口和出口在不同侧
- 出队时采用 BLPOP 或 BRPOP
使用场景
存储有序的字符串列表。如消息队列、最新消息列表等。
Set 类型
是 String 类型的无序集合。集合成员是唯一的,即集合中不能出现重复的数据。
集合对象的编码可以是 intset 或者 hashtable。
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
类似 Java 的 HashSet。
特征:
- 无序
- 元素不可重复
- 查询速度快
- 支持交集、并集、差集等功能
Set 常用命令
| 序号 | 命令 | 描述 |
|---|---|---|
| 1 | SADD key member1 [member2] | 向集合添加一个或多个元素 |
| 2 | SREM key member1 [member2] | 移除集合中一个或多个元素 |
| 3 | SCARD key | 获取集合的成员数(元素个数) |
| 4 | SISMEMBER key member | 判断 member 元素是否是集合 key 的成员 |
| 5 | SMEMBERS key | 返回集合中的所有元素 |
| 6 | SINTER key1 [key2] | 返回给定所有集合的交集 |
| 7 | SDIFF key1 [key2] | 返回第一个集合与其他集合之间的差异(差集)。 |
| 8 | SUNION key1 [key2] | 返回所有给定集合的并集 |
使用场景
存储无序的唯一元素,如标签、好友列表等。
SortedSet 类型
Redis 的 SortedSet 是一个可排序的 set 集合。
SortedSet 中每个元素都会关联一个 double 类型的分数 score,可以基于 score 属性对元素排序,底层的实现是一个跳表(SkipList)+ hash 表。
有序集合的成员不可重复,但 score 可重复。
与 Java 中的 TreeSet 类似,但底层数据结构差别很大。
特征:
- 可排序
- 元素不可重复
- 查询速度快
因为 SortedSet 的可排序性,经常被用来实现排行榜这样的功能。
SortedSet 常用命令
| 命令 | 描述 |
|---|---|
| ZADD key score1 member1 [score2 member2] | 向有序集合添加一个或多个成员,若已存在则更新其 score 值 |
| ZREM key member [member …] | 移除有序集合中的一个或多个成员 |
| ZSCORE key member | 返回有序集中,成员的 score 值 |
| ZRANK key member | 返回有序集合中指定成员的排名(索引) |
| ZCARD key | 获取有序集合的成员个数 |
| ZCOUNT key min max | 计算在有序集合中指定区间分数的成员数 |
| ZINCRBY key increment member | 有序集合中对指定成员的分数加上增量 increment |
| ZRANGE key start stop [WITHSCORES] | 通过索引区间返回有序集合指定区间内的成员 |
| ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] | 通过分数返回有序集合指定区间内的成员 |
| ZDIFF、ZINTER、ZUNION | 求差集、交集、并集 |
注意:所有的排名默认都是升序,如果要降序则在命令的 Z 后添加 REV 即可,如:
使用场景
存储有序的唯一元素,每个元素都关联一个分数,常用于排行榜、计分系统等。
使用场景分析
- 缓存:使用字符串存储缓存数据,列表存储消息队列,集合存储用户标签等。
- 计数器:使用字符串的 INCR 命令实现计数器功能。
- 会话管理:使用哈希表存储用户会话信息,如用户登录状态、权限等。
- 发布订阅:使用发布订阅功能实现消息广播。
- 排行榜:使用有序集合存储用户分数,实现排行榜功能。
- 实时统计:使用计数器、有序集合等数据结构实现实时统计功能。