Redis笔记
花了大概两天完成,Java8内容的学习,比预期的要上了短一些,本来打算按照学习计划先进行Java开发框架的学习,但是发现面试的时候Redis考点会更多一点,所以将Redis部分的学习提前,预定大概10天完成(黑马Redis教程)
教程包括了:八种不同的数据结构,两个消息队列,四个相关的运维操作,Scrip脚本,事务操作
NoSQL
SQL是关系型数据库,而NoSQL是非关系型数据库
与SQL的区别
结构化
SQL高度结构化,每个字段每个值都会有严格的要求,一般难以修改。而NoSQL是非结构化的,对于key没有严格要求,支持自定义,还可以键值类型,列类型,文档存储,Graph存储,相对SQL,结构便于修改
关联性
SQL有外键的约束,数据是相关联的,NoSQL没有关联(程序员手动维护)
SQL查询
只要是SQL都可以使用相同的查询语句查询,而NoSQL没有固定的语法格式
每一个类型的数据查询方式不同
事务
SQL有事务满足ACID,而NoSQL只满足BASE
总结
Redis
基本介绍
Remote Dictionary Server 远程词典服务器,是一个基于内存的键值型NoSQL数据库,以下是Redis的基本特征
键值型:value支持多种不同数据结构,功能丰富
单线程:每个命令具备原子性(Redis 6可以多线程处理网络请求)
高性能:低延迟,速度快(基于内存,IO多路复用,良好的编码【C语言编写】)
持久化:内存以往是不持久化的,而Redis定期存入磁盘,支持持久化
高可用:支持主从集群,分片集群
语言支持:支持多种语言的客户端
常用命令
我们一般的redis数据库会配置在Linux环境下,之后可以使用Windows的GUI软件RESP来使用Linux下的数据库
再Linux下装好redis后,可以使用如下的指令
命令行客户端
1 | redis-cli |
服务端启动脚本
1 | redis-server |
哨兵启动脚本
1 | redis-sentinel |
可以在redis.conf中设置,允许访问的地址,密码,是否后台运行等
再用如下的指令指定配置文件启动
1 | redis-server redis.conf |
利用如下指令查找开启的进程
1 | ps -ef | grep redis |
杀死对应端口的进程
1 | kill -9 2574 |
用命令行客户端连接redis
1 | redis-cli -a ****** |
连接成功后,ping和服务端交互
1 | ping |
还可以进行存取数据
1 | 127.0.0.1:6379> set name jack |
再windows宿主机使用如下指令连接(虚拟机网络适配器改为桥接连接模式)
1 | redis-cli -h 192.168.104.52 -p 6379 -a ****** |
使用GUI客户端连接
网址链接: https://github.com/lework/RedisDesktopManager-Windows
Redis数据结构
Redis是一个键值对形式存储的数据库,key一般是String类型的,不过Value的类型非常多种多样
其中前五种是基本数据类型,后三种是特殊数据类型
数据类型的具体使用详见 https://redis.io/docs/latest/commands
如果在连接到redis下的客户端中可以使用如下指令获取帮助
1 | help @数据类型 |
例如查看String的相关指令
1 | help @String |
Key的层级格式
Redis没有类似MySQL中的Table概念,而所有的键值对都是存储在一起的,怎么区分不同类型的key?
例如需要存储用户,商品信息到redis,一个用户的id是1,而另一个商品id也为1
而为了解决这类的问题,redis引入了key的层级结构:Redis的key允许有多个单词形成层级结构,多个单词之间用:隔开,格式如下
1 | 项目名称:业务名称:类型:id |
格式并非固定不变,可以根据需求删除或者添加词条
user相关的key:com.user:1
product相关的key:com.product:1
Redis通用命令
虽然有非常多的数据类型以及相关操作,但是其中也有一些通用的命令
KEYS
查看符合模板的所有key,不建议在Redis服务器端使用,会阻塞所有的其他指令
1 | KEYS pattern |
例如:返回所有的键值
1 | KEYS * |
返回a开头的所有键值
1 | KEYS a* |
DEL
删除一个指定的键值(例如age)
1 | DEL age |
也可以删除多个
1 | DEL k1 k2 k3 |
MSET
批量插入键值对
1 | MSET k1 v1 k2 v2 k3 v3 k4 v4 |
EXISTS
判断是否存在键值
1 | EXISTS k4 |
EXPIRE
给一个key设置有效期,有效期到达时key会被删除
1 | EXPIRE key second |
1 | EXPIRE name 5 |
TTL
查看一个键的有效期
1 | TTL key |
其中返回-1代表永久有效 -2为无效,其余为有效的秒数
1 | TTL k1 |
String类型
是字符串类型,是Redis中最简单的存储类型,value是字符串,根据不同的格式又分为了三类:String 普通字符串 int 整数类型 float 浮点类型
无论是哪一种格式存储,底层都是字节数组形式,只是编码方式不同,字符串类型的最大空间不可以超过512M
以下是String类型常见的命令
SET
添加或者修改一个存在的String类型的键值对
1 | set k1 123 |
GET
根据key获取String类型的value
1 | get k1 |
MSET
批量添加多个String类型的的键值对
1 | MSET t1 1 t2 2 t3 3 |
MGET
根据多个key获取多个String类型的value
1 | MGET k1 k2 k3 |
INCR
让一个整型的key自增1
1 | get 1 |
1 | INCR 1 |
INCRBY
让一个整形的key自增并指定步长,例如incrby num 2让num自增2
在INCR的基础上增加步长
1 | INCRBY 1 4 |
INCRBYFLOAT
让一个浮点类型的数字自增并指定步长
1 | append 2 3.1415296 |
SETNX
添加一个String类型的键值对,前提是这个key不存在,否则不执行
k1以及存在,不执行语句
1 | SETNX k1 1 |
SETEX
添加一个String类型的键值对,并且指定有效期
1 | SETEX key seconds value |
设置键3值12,持续30每秒
1 | SETEX 3 30 12 |
或者可以这么写
1 | set 3 12 ex 30 |
Hash类型
Hash类型,又称为散列,它的value是一个无序字典,类似于Java中的HashMap结构,String结构是将对象序列化为JSON字符串后存储,当需要修改某个字段的时候很不方便
而Hash结构可以将对象中的每个字段独立存储,可以针对单个字段作增删改查
HSET
添加或者修改hash类型key的field值
1 | hset key field value |
1 | hset hash1 field value |
HGET
获取一个hash类型的key的field值
1 | HGET key field |
1 | hget hash1 field |
HMSET
批量添加多个hash类型key的field值
1 | HMSET hash1 field2 value2 field3 value3 |
HMGET
批量获取多个hash类型的key的field值
1 | HMGET hash1 field field1 field2 |
HDEL
删除指定hash中的某个字段
1 | HDEL hash fieldString |
HGETALL
获取一个hash类型的key中所有的field和value
1 | HGETALL hash1 |
HKEYS
获取一个hash类型的所有field
1 | HKEYS hash1 |
HVALS
获取一个hash类型的所有value
1 | HVALS hash1 |
HINCRBY
让一个hash类型key的字段值自增,并指定步长
1 | HSET hash fieldInt 1 |
HSETNX
添加一个hash类型key的field值,前提是field不存在,否则不执行(就是不允许修改存在的键的值)
1 | HSETNX hash fieldString HelloWorld |
List类型
对于List而言,可以使用该数据类型进行模拟栈:只需要入口和出口在同一边,如LPUSH+LPOP或者RPUSH+RPOP
也可以模拟一个队列:需要入口和出口在不同边即可,如RPUSH+LPOP或者RPUSH+LPOP
阻塞队列的模拟:入口出口不同边,取出采用BLPOP或者BRPOP
基本介绍
Redis中的List类型,和Java中的LinkedList类似,可以看作是一个双向链表的结构,既支持正向检索也可以支持反向检索
特征:有序,元素可以重复,插入和删除较快,查询效率一般
以下是List的常见命令
LPUSH
向列表左侧插入一个或者多个元素
1 | LPUSH key element ... |
1 | LPUSH list a b c d e f g |
LPOP
移除并返回列表左侧的第一个元素,没有则返回nil
1 | LPOP key |
1 | LPOP list |
RPUSH
向列表右侧插入一个或者多个元素
1 | RPUSH list a b c d e f g h |
RPOP
移除并返回列表右侧的第一个元素
1 | RPOP list |
LRANGE
返回一段角标范围内的所有元素
1 | LRANGE key star end |
1 | LRANGE list 1 3 |
BLPOP与BRPOP
和LPOP,RPOP类似,只是在没有元素时等待指定时间,而不是返回nil
1 | BLPOP list 60 |
其中list本来没有值,进入阻塞等待最多60s,新创建的客户端加入list 数据 target数据被读到
Set类型
Redis的Set结构和Java中的HashSet类似,可以看为是一个value为null的HashMap,因为是一个hash表,因此具备和HashSet类似的特征:无序,元素不可重复,查找快,支持交集、并集、差集的功能
以下是Set类型常见的命令
SADD
向set中添加一个或者多个元素
1 | SADD key member ... |
1 | SADD set a b c d e f g |
SREM
移除set中的指定元素
1 | SREM key member ... |
1 | SREM set a b c |
SCARD
返回set中的元素个数
1 | SCARD key |
1 | SCARD set |
SISMEMBER
判断一个元素是否存在于set中
1 | SISMEMBER key member |
1 | SISMEMBER set g |
SMEMBERS
获取set中的所有元素
1 | SMEMBERS set |
前置操作
1 | SADD set1 a b c d e f |
SINTER
求两个集合的交集
1 | SINTER set1 set2 |
1 | 1) "b" |
SDIFF
求两个集合的差集
1 | SDIFF set1 set2 |
1 | 1) "c" |
SUNION
求两个集合的并集
1 | SUNION set1 set2 |
1 | 1) "b" |
SortedSet类型
Redis的SortedSet是一个可排序的set集合,与Java中的TreeSet有些类似,但是底层数据结构差别巨大,SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层是一个跳表(Skip List)加上hash表
以下是SortedSet的特征:可排序 元素不重复 查询速度快
因为SortedSet的可排序性,经常用于实现排行榜等功能
以下是Sorted的常见命令,所有排名默认为升序,降序在命令Z后加REV即可
1 | ZREVRANGE |
ZADD
添加一个或者多个元素到sorted set,如果与存在则更新其score值
1 | ZADD key score member |
1 | ZADD sortedset 1 Hello |
ZREM
删除sorted set中的一个元素
1 | ZREM key member |
1 | zrem sortedset HelloWorld |
ZSCORE
获取sorted set中指定元素的score值
1 | ZSCORE key member |
1 | ZSCORE sortedset Hello |
ZRANK
获取sorted set中的指定元素排名
1 | ZRANK key member |
1 | ZRANK sortedset Hello |
ZCARD
获取sorted set中的元素个数
1 | ZCARD key |
1 | zcard sortedset |
ZCOUNT
统计指定范围内元素的个数
1 | ZCOUNT key min max |
1 | ZCOUNT sortedset 2 5 |
ZINCRBY
让sorted set 中指定score元素自增,指定步长
1 | ZINCRBY key increment member |
1 | ZINCRBY sortedset 4 1 |
ZRANGE
按照score排序后,获取指定排名范围内的元素
1 | ZRANGE key min max |
1 | ZRANGE sortedset 0 1 |
ZRANGEBYSCORE
按照score排序后,获取指定score范围内的元素
1 | ZRANGEBYSCORE key min max |
1 | ZRANGEBYSCORE sortedset 0 44 |
ZDIFF、ZINTER、ZUNION
求差集、交集、并集
和Set类中的类似,不再过多叙述