前言
Redis是一个Key-Value形式的非关系型数据库(NoSQL),因有着丰富的数据类型和特性而被广泛应用,这篇文章主要对Redis数据类型及应用场景进行介绍。
什么是NoSQL?
在正式介绍Redis数据类型之前,先简单介绍下数据库分类
| 中文名 | 英文名 | 定义 | 存储形式 | ACID支持情况 | CAP支持情况 | 数据库举例 |
|---|---|---|---|---|---|---|
| 关系型数据库 | Relational database | 采用了关系模型来组织数据的数据库 | 二维表格 | 支持ACID规则 | 满足CP,但A不完美 | MySQL、Oracle、PostgreSQL |
| 非关系型数据库 | NoSQL(Not Only SQL) | 泛指非关系型的数据库,不保证关系数据的ACID特性 | 键值存储、列存储、文档存储等 | 不完全支持ACID规则,追求最终一致性 | 满足AP,但C不完美 | Redis、Memcache、MongoDB |
| 新型数据库 | NewSQL | NewSQL是对各种新的可扩展/高性能数据库的简称 | 多种数据存储形式 | 支持ACID规则 | 满足CAP | TiDB、Google Spanner |
5种基础数据类型
1. String数据类型
String是Redis最基础的数据类型,一个key对应一个value。string是二进制安全的,value可以是任意形式,最大存储容量是512M。
常用操作指令
- GET key 获取指定key的值;
- MSET key value[key value...] 批量设置;
- MGET key[key...] 批量获取;
- DEL key 删除指定key,支持多个;
- EXPIRE key seconds 设置一个key的估期时间(秒);
- PEXPIRE key milliseconds 设置一个key的过期时间(毫秒);
- INCR key 对数字key自增1;
- DECR key 对数字key自减1;
- INCRBY key increment 对数字key进行{increment}的增加;
- DECRBY key decrement 对数字key进行{decrement}的减少;
- SETNX key value 在指定的key不存在时,为key设置指定的值;
应用场景
- 常规的key-value存储;
- 计数器:如阅读量,浏览量;
- 共享session,可以代替MemberCache的作用;
- 字符串键:分布式全局序列
- ......
2. List数据类型
Redis list 列表是简单的字符串列表,按照插入顺序排序。列表最多可存储 2^32 - 1 元素。
常用操作指令
- LPUSH key value1 [value2] 向key的列表左边放入一个元素,key不存在则新建;
- RPUSH key value1 [value2] 向key的列表中右边放入一个元素,key不存在则新建;
- LPOP key 从key的列表最左端弹出一个元素;
- RPOP key 从key的列表最右端弹出一个元素;
- LRANGE key start stop 获取列表key从start到stop的元素;
- BLPOP key timeout 阻塞的从key列表的最左端弹出一个元素,若列表中不存在元素,阻塞等待{timeout}秒,若{timeout}为0,则一直阻塞;
- BRPOP key timeout 阻塞的从key列表的最右端弹出一个元素,若列表中不存在元素,阻塞等待{timeout}秒,若{timeout}为0,则一直阻塞;
应用场景
- 实现阻塞消息队列;
- 实现用户消息列表功能;
- 获取最新内容;
- ......
3. Hash数据类型
Redis hash 是一个键值(key=>value)对集合。其中value是一个 string 类型的 field 和 value 的映射表,hash数据类型 特别适合用于存储对象。
常用操作指令
- HSET key field value 存储一个散列键;
- HSETNX key field value 只有在字段 field 不存在时,存储这个散列键;
- HMSET key field1 value1 [field2 value2 ] 一个key中存储多个filed;
- HGET key field 获取key filed的散列键值;
- HMGET key field1 [field2] 批量获取key中多个filed的值;
- HDEL key field1 [field2] 删除一个或多个哈希表字段;
- HINCRBY key field increment 为哈希表key中的指定字段的整数值加上增量increment
应用场景
- 存储用户信息;
- 存储商品信息;
- ……
4. Set数据类型
Redis 的 Set 是 string 类型的无序集合。集合中不允许存在重复值,根据集合内元素的唯一性,第二次插入的元素将被忽略。 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 2^32 - 1
常用操作指令
- SADD key member1 [member2] 向集合建key中存放元素,若key不存在则新建;
- SREM key member1 [member2] 移除集合中一个或多个元素;
- SMEMBER key 返回集合中所有的元素;
- SCARD key 获取集合键的元素个数;
- SISMEMBER key member 判断{member}元素是否存在于集合键key中;
- SRANDMEMBER key count 从集合键key中选出{count}个元素,不从集合key中删除;
- SPOP key [count] 从集合key中选出{count}元素,并且从集合键中删除
应用场景
- 共同好友列表;
- 实现直播刷礼物、转发、抽奖活动;
- 实现点赞、签到等功能;
- 可能认识的人(通过集合键运算API);
- 电商商品筛选;
- 基于集合键运算API,实现与支付系统时间对账
- ……
5. zSet数据类型
Redis zSet 和 Set 都是string类型元素的集合,且不允许重复的成员。 不同的是zSet每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zSet的成员是唯一的,但分数(score)却可以重复。
常用操作指令
- ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数;
- ZCARD key 获取有序集合的成员数;
- ZCOUNT key min max 计算在有序集合中指定区间分数的成员数;
- ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment;
- ZRANK key member 返回有序集合中指定成员的索引;
- ZREM key member [member ...] 移除有序集合中的一个或多个成员;
应用场景
- 游戏排行榜;
- 带权重的消息队列;
- ......
3种特殊数据类型
1. Geospatial 地理位置
Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,该功能在 Redis 3.2 版本新增。
常用操作指令
GEOADD:用于存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中;
GEOADD key longitude latitude member [longitude latitude member ...]
GEOPOS:用于从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil;
GEOPOS key member [member ...]
GEODIST:用于返回两个给定位置member1,member2之间的距离;
- m:米,默认单位;
- km:千米;
- mi:英里;
- ft:英尺
GEODIST key member1 member2 [m|km|ft|mi]
GEORADIUS:以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素;
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
GEORADIUSBYMEMBER:根据存储在位置集合里面的某个地点获取指定范围内的地理位置集合;
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
- m:米,默认单位;
- km:千米;
- mi:英里;
- ft:英尺;
- WITHDIST:在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回;
- WITHCOORD:将位置元素的经度和纬度也一并返回;
- WITHHASH:以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大;
- COUNT:限定返回的记录数;
- ASC:查找结果根据距离从近到远排序;
- DESC:查找结果根据从远到近排序
GEOHASH:返回一个或多个位置对象的 geohash 值。
GEOHASH key member [member ...]
应用场景
- 附近的人
2. Hyperloglog 基数统计
Redis HyperLogLog 是用来做基数统计的算法, 其优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、非常小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以不能像集合那样,返回输入的各个元素。
什么是基数?
比如数据集 {1, 3, 5, 7, 5, 7, 8},那么这个数据集的基数集为 {1, 3, 5 ,7, 8},基数(不重复元素)为5。基数估计就是在误差可接受的范围内,快速计算基数。
常用操作指令
PFADD:添加指定元素到 HyperLogLog 中。
PFADD key element [element ...]
PFCOUNT:返回给定 HyperLogLog 的基数估算值。
PFCOUNT key [key ...]
PFMERGE:将多个 HyperLogLog 合并为一个 HyperLogLog
PFMERGE destkey sourcekey [sourcekey ...]
应用场景
- 适合做页面统计
3. Bitmap 位图场景
由多个二进制位组成的数组,数组中的每个二进制位都有与之对应的偏移量(从 0 开始),通过这些偏移量可以对位图中指定的一个或多个二进制位进行操作。
常用操作指令
SETBIT:可以为位图指定偏移量上的二进制位设置值,offset 必须大于等于 0,value 只能是 0 或 1。此命令的时间复杂度是 O(1)。
SETBIT key offset value
GETBIT:使用 GETBIT 命令可以获取位图指定偏移量上的二进制位的值。此命令的时间复杂度是 O(1)。
GETBIT key offset
如果输入的偏移量超过了位图目前拥有的最大偏移量,将返回 0 作为结果。
BITCOUNT:通过 BITCOUNT 命令可以统计位图中值为 1 的二进制位数量。此命令的时间复杂度是 O(n)。
BITCOUNT key [start end]
BITPOS:通过执行 BITPOS 命令,在位图中查找第一个被设置为指定值的二进制位,并返回这个二进制位的偏移量。
BITPOS key value [start end]
BITOP:通过 BITOP 命令,对一个或多个位图执行指定的二进制位运算,并将运算结果存储到指定的键中。
BITOP operation destkey key [key ...]
应用场景
- 用户行为记录器
- 用户上线统计
新特性 -- Stream
Redis Stream 是 Redis 5.0 版本新增加的数据结构。
Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它无法保证消息持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。
简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。而 Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。
总结
这篇文章整体介绍了Redis基础数据类型,操作指令,以及主要应用场景,在Redis系列的下一篇中会介绍Redis各种数据类型的底层实现。