一、基础知识
redis默认有16个数据库
-
16个数据库:DB0~DB15
-
默认使用DB 0,可以使用
select n
切换到DB n -
dbsize
可以查看当前数据库的大小,与key数量相关127.0.0.1:6379[15]> config get databases //命令行查看数据库数量databases 1) "databases" 2) "16" 127.0.0.1:6379[15]> select 15 //切换数据库DB 15 OK 127.0.0.1:6379[15]> dbsize //查看当前数据库大小,不同数据库之间的数据是不能互通的,并且dbsize是根据库中key的个数 (integer) 0
keys *
:查看当前数据库中所有的key(注意:查询到的是key,而不是value)。
flushdb
:清空当前数据库中的键值对。
flushall
:清空所有数据库中的键值对(DB0~DB15)。
127.0.0.1:6379[15]> set name czl
OK
127.0.0.1:6379[15]> set age 18
OK
127.0.0.1:6379[15]> keys *
1) "name"
2) "age"
127.0.0.1:6379[15]> select 0
OK
127.0.0.1:6379> keys * //在DB0中不能获得DB15中所记录的键值对
(empty array)
127.0.0.1:6379>
Redis是单线程的,是基于内存操作的
所以Redis的性能瓶颈不是CPU,而是机器内存和网络宽带。
那就出现一个问题,为什么Redis的速度这么快,性能这么高呢?QPS(每秒查询率)达到10W+ ?
Redis为什么单线程还这么快?
- 误区1:高性能的服务器一定是多线程的
- 误区2:多线程(CPU上下文会切换)一定比单线程效率高
核心:Redis是将所有数据放在内存中的,所以说使用单线程去操作效率就是最高的,多线程(上下文会切换,就会有耗时的操作),对于内存系统来说,如果没有上下文切换效率就是最高的,多次读写都是在一个CPU上的,在内存存储数据情况下,单线程就是最佳的方案。
二、五大基本数据类型
Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库、高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合、位图、hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。
Redis-key
在redis中无论什么数据类型,在数据库都是以key-value的形式保存的,通过进行Redis-key的操作,来完成数据库中数据的操作
下面学习的命令
exists key
:判断键是否存在del key
:删除键值对move key db
:将键值对移动到指定的数据库expire key second
:设置键值对的过期时间type key
:查看value的数据类型
127.0.0.1:6379> keys * //查看当前数据库所有的key
1) "name"
2) "age"
127.0.0.1:6379> set gender nan //设置一个gender-nan的键值对
OK
127.0.0.1:6379> keys *
1) "name"
2) "age"
3) "gender"
127.0.0.1:6379> move gender 1 //将key为gender的键值对移动到DB1数据库
(integer) 1
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "gender"
127.0.0.1:6379[1]> del gender //删除key为gender的键值对
(integer) 1
127.0.0.1:6379[1]> keys *
(empty array)
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> EXISTS gender
(integer) 0 //存在则返回1,不存在则返回0
127.0.0.1:6379> EXISTS name
(integer) 1
127.0.0.1:6379> set gender nan
OK
127.0.0.1:6379> EXPIRE gender 15 //设置键值对的过期时间
(integer) 1
127.0.0.1:6379> ttl gender
(integer) 6
127.0.0.1:6379> ttl gender
(integer) 5
127.0.0.1:6379> ttl gender
(integer) 4
127.0.0.1:6379> ttl gender
(integer) 3
127.0.0.1:6379> ttl gender
(integer) 1
127.0.0.1:6379> ttl gender
(integer) 0
127.0.0.1:6379> ttl gender
(integer) -2
127.0.0.1:6379> get gender
(nil)
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> type name
string
127.0.0.1:6379> type age
string
关于TTL(ttl)
命令
Redis的key,通过TTL命令返回key的过期时间,一般来说有三种结果
- 当前key没有设置过期时间,则返回-1
- 当前key有设置过期时间,而且key已经过期,则返回-2
- 当前key有设置过期时间 ,并且key还没有过期,故会返回key的正常剩余时间。
关于重命名RENAME
和RENAMENX
RENAME key newkey
:修改key的名称RENAMENX key newkey
:仅当newkey不存在时,将key改名为newkey
127.0.0.1:6379> RENAME name name2 //将键值对中key为name的键值对的key修改成name2
OK
127.0.0.1:6379> keys *
1) "age"
2) "name2"
127.0.0.1:6379> RENAMENX name2 age//age存在所以不能将键值对key为name2的key修改成age
(integer) 0
127.0.0.1:6379> RENAMENX name2 name//name不存在所以修改成功
(integer) 1
127.0.0.1:6379> keys *
1) "name"
2) "age"
更多的学习命令可以去官网查询api:https://www.redis.net.cn/order/
1、String(字符串)
普通的set、get省略
命令 | 描述 | 示例 |
---|---|---|
APPEND key value | 向指定的key的value后追加字符串 | |
DECR/INCR key | 将指定key的value数值进行+1/-1 | |
INCRBY/DECRBY key n | 按指定的步长对数值进行加减 | |
INCRBYFLOAT key n | 为数值加上浮点型数值(注:没有减,加上负数即是减) | |
STRLEN key | 获取key保存值的字符串长度(注:.也算一个长度) | |
GETRANGE key start end | 按起止位置获取字符串(闭区间,起止位置都取) | |
SETRANGE key offset value | 用指定的value 替换key中 offset开始的值 | |
GETSET key value | 如果key所对应的键值对存在,则将给定key的值设为value,并返回key的旧值(old value);如果key所对应的键值对不存在,则返回nil | |
SETNX key value | 仅当key不存在时进行set | |
SETEX key seconds value | set设置键值对并设置过期时间 | |
MSET key1 value1[key2 value2..] | 批量设置键值对 | |
MSETNX key1 value1[key2 value2..] | 批量设置键值对,仅当参数中所有的key都不存在时执行(注:只要设置的值中有一个key在原键值对中已经存在,则该语句不执行,因此该语句具有原子一致性) | |
MGET key1 [key2 ..] | 批量获取多个key保存的值 | |
PSETEX key milliseconds value | 和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间(注:1s=1000ms) |
String类似的应用场景:value除了是字符串还可以是数字,用途举例:
- 计数器
- 统计多单位的数量:uid:10000:follow 0
- 粉丝数量
- 对象储存缓存
2、 List(列表)
1.Redis列表是简单的字符串列表,按照插入顺序排序,可以添加一个元素到列表的头部(左侧)也可以添加到尾部(右侧)
2.一个列表最多可以包含2的32次方-1个元素(4294967295,每个列表可以包含超过40亿个元素)
3.list中插入的值是可以重复的
首先列表可以经过规则定义将其变为队列(先进先出)、栈(先进后出)、双端队列等
正如图中Redis中List是可以进行双端操作的,所以命令也就分成了LXXX和RLLL两类,有时候L也表示List例如LLEN
插入list的值是可以重复的
命令 | 描述 | 示例 |
---|---|---|
LPUSH/RPUSH key value1[value2..] | 从左边/右边向列表中PUSH值(一个或者多个) | |
LRANGE key start end | 普通的get mylist是无法获取list的值的,需要获取起始和截止位置的范围(索引会从左往右递增) | |
LPUSHX/RPUSHX key value | 向已经存在的列明中push值(一个或者多个) | |
LINSERT key BEFORE|AFTER pivot value | 在指定列表元素的前/后插入value | |
LLEN key | 查看列表长度 | |
LINDEX key index | 通过索引获取列表元素(注:通过索引查询而不是对应的位置) | |
LSET key index value | 通过索引为元素设值 | |
LPOP/RPOP key | 从最左边/最右边移除值并返回移除的值 | |
RPOPLPUSH source destination | 将列表的尾部(右)最后一个值弹出,并返回该值,然后将弹出的值加到另一个列表的头部(注:我测试的版本没有LPOPLPUSH命令) | |
LTRIM key start end | 通过下标截取指定范围内的列表 | |
LREM key count value | List中是允许value重复的count>0 :从头部搜索,然后删除指定的value至多删除count个count<0 :从尾部开始搜索,然后删除指定的value至多删除count个count=0 :删除列表中所有的指定value | |
BLPOP/BRPOP key1[key2] timout | 移出并获取列表第一个/最后一个元素,如果列表没有元素,那么则会阻塞列表直到等待超时或发现可弹出元素位置 | |
BRPOPLPUSH source destination timeout | 和RPOPLPUSH 功能相同,如果列表没有元素会阻塞列表知道等待超时或发现可弹出元素为止。(注:我测试的版本没有BLPOPLPUSH命令)) |
LIST小结
- list实际上是一个链表
- 如果key不存在,则创建新的链表
- 如果key存在,则新增内容
- 如果移除了所有值,空链表,也代表不存在
- 在两边插入或者改动值,效率最高!修改中间元素,效率相对较低
应用场景:
消息排队,消息队列(Lpush Rpop),栈(Lpush Lpop)
3、Set(集合)
1.Redis的Set是string类型的无序集合,集合成员是唯一的,这就意味着集合中不能出现重复的数据。
2.Redis集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
3.集合中最大的成员数是2的32次方-1(4294967295,每个集合可储存40多亿个成员)。
命令 | 描述 | 示例 |
---|---|---|
SADD key member1[member2...] | 向集合中无序增加一个/多个成员 | |
SCARD key | 获取集合的成员数量 | |
SMEMBERS key | 返回集合中所有的成员 | |
SISMEMER key member | 查询member元素是否是集合的成员,结果是无序的 | |
SRANDMEMBER key [count] | 随机返回集合中count个成员,count缺省值为1 | |
SPOP key [count] | 随机移除返回集合中count个成员,count缺省值为1 | |
SMOVE sourve destination member | 将source集合的成员member移动到destination集合中去 | |
SREM key member1 [member2..] | 移除集合中一个/多个成员(注:由图可知,该操作非原子性) | |
SDIFF key1 [key2..] | 返回所有集合的差集key1-key2-… | |
SDIFFSTORE destination key1 [key2...] | 在SDIFF的基础上,将结果保存到集合中覆盖(注:不能保存到其他类型的key!!!,且如果destination不存在则创建) | |
SINTER key1 [key2...] | 返回所有集合的交集 | |
SINTERSTORE destination key1 [key2...] | 在SINTER的基础上,储存结构到集合中覆盖(注:不能保存到其他类型的key!!!,且如果destination不存在则创建) | |
SUNION key1 [key2...] | 返回所有集合的并集 | |
SUNIONSTORE destination key1 [key2...] | 在SUNION的基础上,存储结果到集合中覆盖(注:不能保存到其他类型的key!!!,且如果destination不存在则创建) | |
SSCAN key cursor [MATCH pattern] [COUNT count] | 在大量数据环境下,使用此命令遍历集合中元素,每次遍历部分 | 暂无 |
应用场景
- 黑名单
- 白名单
4、Hash(哈希)
1.Redis hash是一个string类型的field和value的映射表,hash特别适用于存储对象。
2.Set就是一种简化的Hash,只变动key,而value使用默认值填充。可以将一个Hash表作为一个对象进行存储,表中存放对象的信息。
命令 | 描述 | 示例 |
---|---|---|
HSET key field value | 将哈希表key中的字段field的值设为value。重复设置同一个field会覆盖,返回0 | |
HMSET key field1 value1 [field2 value2..] | 同时将多个field-value(域-值)对设置到哈希表key中 | |
HSETNX key field value | 只有在字符按field不存在的时,设置哈希表字段的值 | |
HEXISITS key field | 查看哈希表key中,指定的字段filed(域)是否存在 | |
HGET key field | 获取存储在哈希表中指定字段的值 | |
HMGET key field1 [field2..] | 获取所有给定字段的值 | |
HGETALL key | 获取在哈希表key中所有的字段field(域)和值 | |
HKEYS key | 获取哈希表key中所有的字段field(域) | |
HLEN key | 获取哈希表中字段field(域)的数量 | |
HVALS key | 获取哈希表中所有的值 | |
HDEL key field1 [field2..] | 删除哈希表key中一个/多个field字段(域) | |
HINCRBY key field n | 哈希表 key 中的指定字段的整数值加上增量n,并返回增量,结果也是整数型字符按(只适用于整数型字段) | |
INCRBYFLOAT key field n | 为哈希表 key 中的指定字段的浮点数值加上增量 n(注:我所测试的版本不存在减的命令,要想实现减可以使用-n) | |
HSCAN key cursor [Match pattern] [COUNT count] | 迭代哈希表中的键值对 | 暂无 |
Hash适用于存储变更的数据user name age,尤其是用户信息之类经常变动的信息!Hash更适合于对象的存储,String更加适合字符串的存储!
应用场景:
- 双11活动日,推出抢购活动,每种商品上线1000件,超卖等实际问题
5、Zset(有序集合)
1.与Set不同的是每个元素都会关联一个double类型的分数(score)。redis正是通过分数来为集合中的成员进行从小到大的排序的。
score相同:按字典顺序排序
2.有序集合的成员是唯一的,但分数(score)却可以重复
命令 | 描述 | 示例 |
---|---|---|
ZADD key score member1 [score2 member2...] | 向有序集合中添加一个或者多个成员,或者更新已经存在的成员分数 | |
ZCARD key | 获取有序集合的成员数量 | |
ZCOUNT key min max | 计算在有序集合中指定区间score的成员数 | |
ZINCRBY key n member | 有序集合中对指定成员的分数加上增量 n | |
ZSCORE key member | 返回有序集合中,member成员的分数值 | |
ZRANK key member | 返回有序集合中指定成员的索引 | |
ZRANGE key start end (withscores) | 通过索引区间返回有序集合成指定区间内的成员 | |
ZRANGEBYLEX key min max [LIMIT offset count] | 通过字典区间返回有序集合的成员,加上limit就是分页,从offset记录开始查询count条记录并显示 | |
ZRANGEBYSCORE key min max | 用过分数返回有序集合指定区间内的成员,-inf和+inf分别表示最小值和最大值,只支持开区间() | |
ZLEXCOUNT key min max | 在有序集合中计算指定字典区间内成员数量 | |
ZREM key member1 [member2..] | 移除有序集合中一个/多个成员 | |
ZREMRANGEBYLEX key min max | 移除有序集合中给定字典区间的所有成员 | |
ZREMRANGEBYRANK key start stop | 移除有序集合中给定排名区间(索引)的所有成员 | |
ZREMRANGEBYSCORE key min max | 移除有序集合中给定的分数区间的所有成员 | |
ZREVRANGE key start end | 首先按分数从大到小排序,然后通过排序后的索引输出 | |
ZREVRANGEBYSCORRE key max min | 首先按score从大到小排序,返回集合中分数在[min,max]中的成员 | |
ZREVRANGEBYLEX key max min | 首先通过字典顺序从大到小排序,然后显示[max,min]中字典区间的成员 | |
ZREVRANK key member | 首先根据score从大到小排序,返回member成员的索引 | |
ZINTERSTORE destination numkeys key1 [key2 ..] | 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中,numkeys:表示参与运算的集合数,将score相加作为结果的score | |
ZUNIONSTORE destination numkeys key1 [key2..] | 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中,默认是将两个集合的成员score相加,如果加上AGGREGATE MIN 则是取两个集合成员score的最小值 | |
ZSCAN key cursor [MATCH pattern\] [COUNT count] | 迭代有序集合中的元素(包括元素成员和元素分值) | 暂无 |
应用场景
- set排序 :1.存储班级成绩表 2.工资表排序
- 普通消息:1.重要消息 2.带权重进行判断
- 排行榜应用实现,取TOP N测试