Redis 简介
REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 开发的 key-value 存储系统。
Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
Redis 官网:https://redis.io/ Redis 在线测试:http://try.redis.io/
Redis的优势
性能极高 – Redis 能读的速度是 110000次/s,写的速度是 81000次/s 。
丰富的数据类型 – Redis 支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
原子 – Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过 MULTI 和 EXEC 指令包起来。
丰富的特性 – Redis 还支持 publish/subscribe, 通知, key 过期等等特性。
Redis与其他 key-value 存储有什么不同?
Redis 有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis 的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
Redis 运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样 Redis 可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
Redis 数据类型
Redis 支持九种数据类型:string(字符串),hash(哈希),list(列表),set(集合)、zset(sorted set:有序集合),以及 HyperLog、bit、geo、stream。
String(字符串)
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象。
SET key value 设置指定 key 的值
大家注意一下设置字符串类型变量的做法,其中字符串可以用双引号包含,也可以用单引号包含,还可以不带任何符号
GET key 获取指定 key 的值
代码语言:javascript复制set 命令不区分大小写, 但是 key 和 value 区分大小写
set mykey lalala
get mykey
set 命令将取代现有的任何已经存在的 key。set 命令还有一个提供附加参数的选项
让 set 命令只有在没有相同 key 的情况下成功
代码语言:javascript复制> set mykey newval nx
可以让 set 命令在有相同 key 值的情况下成功:
代码语言:javascript复制> set mykey newval xx
mset 和 mget 命令一次性完成多个 key-value 的对应关系,使用 mget 命令,Redis 返回一个 value 数组:
代码语言:javascript复制> mset a 10 b 40
> mget a b
如果 key 对应的值存在,则会用 value 覆盖旧值,同时返回旧值,如果 key 对应的值不
代码语言:javascript复制getset key value
获取 key 的子字符串命令:getrange key start end 返回key对应的下标从 start 到 end (包含)的子字符串。
替换部分值命令:setrange key offset value,从 offset 位置开始,把值替换为value。
统计字符串长度的命令:strlen key,返回字符串的长度。
追加值的命令:append key value,把value追加到原值的末尾。
List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
头部(左侧)<----------尾部(右侧)
- lpush 命令插入一个新的元素到头部
- rpush 命令插入一个新元素到尾部
- lrange 需要两个索引,0 表示 list 开头第一个,-1 表示 list 的倒数第一个,即最后一个。-2 则是 list 的倒数第二个,以此类推。
redis 127.0.0.1:6379> DEL runoob
redis 127.0.0.1:6379> lpush runoob redis
(integer) 1
redis 127.0.0.1:6379> lpush runoob mongodb
(integer) 2
redis 127.0.0.1:6379> lpush runoob rabitmq
(integer) 3
redis 127.0.0.1:6379> lrange runoob 0 10
1) "rabitmq"
2) "mongodb"
3) "redis"
在 Redis 的命令操作中,还有一类重要的操作 pop,它可以弹出一个元素,简单的理解就是获取并删除第一个元素,和 push 类似的是它也支持双边的操作,可以从右边弹出(删除)一个元素也可以从左边弹出一个元素,对应的指令为 rpop 和 lpop.
代码语言:javascript复制> del mylist
> rpush mylist a b c
> rpop mylist
> lrange mylist 0 -1
> lpop mylist
> lrange mylist 0 -1
Redis 提供了阻塞式访问 brpop 和 blpop 命令。用户可以在获取数据不存在时阻塞请求队列,如果在时限内获得数据则立即返回,如果超时还没有数据则返回 nil。
代码语言:javascript复制brpop list 10
brpop mylist 10
可以通过lindex命令读取列表的值
代码语言:javascript复制lindex key index
这两个命令与 lpush 和 rpush 命令很相似,只是当对应 key 不存在时,这两个命令不执行,仅当对应 key 存在时才向头部或尾部插入数据。
可以用 lpush 和 lpop 命令能模拟“先入后出”的堆栈效果。也可以用rpush和rpop命令来模拟堆栈效果,只不过这里是从list的右边加入和弹出元素。
同理可以一端 rpush,另一端 lpop 命令来模拟队列的效果。
用lrange命令获取指定区间内的数据。如果在 lrange 命令里开始索引比结束索引还大,这样的话会返回一个空值。
代码语言:javascript复制lrange key start stop
通过lset命令能修改列表里的元素
代码语言:javascript复制lset key index element
如果要连带 key 删除整个列表,可以用del key命令。
Hashes(哈希)
Redis Hashes 是字符串 field 字段和字符串 value 值之间的映射,因此它们是展现对象的完美数据类型。
例如一个有名、姓、年龄等等属性的用户:一个带有一些字段的 hash 仅仅需要一块很小的空间存储,因此你可以存储数以百万计的对象在一个小的 Redis 实例中。
hmset 命令设置一个多域的 hash 表。
hget 命令获取指定的单域。
hgetall 命令获取指定 key 的所有信息。
hmget 类似于 hget,只是返回一个 value 数组。
该命令的含义是,只有当key和field所对应的value不存在时才会设置对应的value。 hsetnx key field value
代码语言:javascript复制> hmset user:1000 username antirez birthyear 1977 verified 1
> hget user:1000 username
> hget user:1000 birthyear
> hgetall user:1000
> hmget user:1000 username birthyear no-such-field
通过hkeys key命令,能查看该key所对应哈希类型数据的所有field;
通过hvals key命令,能查看key所对应哈希类型数据的所有value;
通过 hgetallkey 命令,能以field和value对的形式查看key对应的哈希类型数据。
hexists命令,能判断key和field对应的value是否存在。
通过 hdel 命令,能删除 key 指定的field数据
Set(集合)
Redis 的 Set 是 string 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。 集合是通过哈希表实现的,所以添加、删除、查找的复杂度都是O(1)。
Redis 集合拥有令人满意的不允许包含相同成员的属性,多次添加相同的元素,最终在集合里只会有一个元素,这意味着它可以非常方便地对数据进行去重操作。一个 Redis 集合的非常有趣的事情是它支持一些服务端的命令从现有的集合出发去进行集合运算,因此你可以在非常短的时间内进行合并(unions),求交集(intersections),找出不同的元素(differences of sets)。
sadd 命令
添加一个 string 元素到 key 对应的 set 集合中,成功返回1,如果元素已经在集合中返回 0,如果 key 对应的 set 不存在则返回错误。
sadd key member1 [member2 member3 ...]
sismember 用于查看集合是否存在,匹配项包括集合名和元素(用于查看该元素是否是集合的成员)。匹配成功返回 1,匹配失败返回 0。
代码语言:javascript复制sismember myset 3
可以通过 sinter命令获取多个key对应集合的交集,该命令的格式如下:
代码语言:javascript复制sinter key [key ...]
可以通过 suion 命令获取多个key对应的并集,该命令的格式如下:
代码语言:javascript复制suion key [key ...]
可以通过 sdiff 命令获取多个key对应的差集,该命令的格式如下:
代码语言:javascript复制sdiff key [key ...]
用 srem 命令删除集合数据
代码语言:javascript复制srem key member [member ...]
如果要删除整个集合对象,则可以用 del key 命令。
zset(sorted set:有序集合)
Redis zset 和 set 一样也是 string 类型元素的集合,且不允许重复的成员。 不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。
zset 的成员是唯一的,但分数(score)却可以重复, 也可以被更新。
zadd key score member
查看集合:zrange 是以升序返回集合,zrevrange 则能以降序的方式返回元素。如果带 WITHSCORES 参数,则会同时展示元素所对应的 score 值。
代码语言:javascript复制0 表示集合第一个元素,-1 表示集合的倒数第一个元素。
> zrange hackers 0 -1
> zrevrange hackers 0 -1
通过 zincrby 命令修改元素的分值
代码语言:javascript复制zincrby key increment member
示例
代码语言:javascript复制redis 127.0.0.1:6379> DEL runoob
redis 127.0.0.1:6379> zadd runoob 0 redis
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 mongodb
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq
(integer) 0
redis 127.0.0.1:6379> > ZRANGEBYSCORE runoob 0 1000
1) "mongodb"
2) "rabitmq"
3) "redis"
zscore 命令获取指定元素的分数
代码语言:javascript复制zscore key member
可以用 zrank 命令获取指定元素member在有序集合里的排名,具体命令格式如下:
代码语言:javascript复制zrank key member
其中排在第一位的索引号是 0。
可以用 zrevrank 命令获取元素在指定有序集合里的倒序排名(倒数多少名),该命令的格式如下:
代码语言:javascript复制zrevrank key member
可以通过 zrem 命令删除 key 指向的有序集合里的一个或多个元素,该命令的格式如下:
代码语言:javascript复制zrem key member
zremrangebyrank 命令删除key所指向的有序集合里排名在start到stop范围的元素
代码语言:javascript复制zremrangebyrank key start stop
此外,还可以通过 zremrangebyscore 命令删除key指向的有序队列里score(分值)在min到max范围内的元素:
代码语言:javascript复制zremrangebyscore key min max
各个数据类型应用场景
各个数据类型应用场景
参考
Redis 数据类型 | 菜鸟教程 https://www.runoob.com/redis/redis-data-types.html
An introduction to Redis data types and abstractions – Redis https://redis.io/topics/data-types-intro
Redis中文网 - Redis开发与运维技术、Redis教程、使用手册 https://www.redis.com.cn/
基于Docker的Redis入门与实战-金华 胡书敏编著-微信读书 https://weread.qq.com/web/reader/f2932520725d0bbff2948bckc81322c012c81e728d9d180