Redis
前言
Redis的简单介绍及使用
一、Redis介绍
- Redis 是开源的,免费的,高性能的 非关系形数据库。
- 数据存储在内存,以key-value形式存储,类似于我们学习的字典 {name: ‘jack’ }
- 可以设置过期时间,过期自动删除,也可以做持久化。
关系型数据库: MySQL
MySQL的缺陷:
1. 读取的时候相对较快, 但是写入数据是比较慢的, 读取速度是1w/s. 写入速度: 1000/s。
2. 读写时容易混淆,会读取出脏数据,需要对Mysql读写做限制.
3. 需要定义严格的表结构,插入数据需要满足完整性约束。
4. 数据存储在磁盘,相对于内存数据库,读写速度慢。
非关系型数据库: Redis 在非关系型数据库中没有表这个概念,也就没有表关系这样的概念,都是k/v 格式的。
Redis 优势:
- 性能极高 – Redis读的速度是11w次/s,写的速度是8.1w次/s ,都是基于内存的,读写速度比较快。
- 丰富的数据类型 – Redis支持 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子性 – Redis的所有操作都是原子性的,要么成功执行,要么失败不执行。支持简单的事务,即原子性,通过MULTI和EXEC指令包起来。如下所有的操作全部执行或者全部不执行
>multi
>set name jack
>set age 23
>set sex male
>exec
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
Redis的缺点:
-
基于内存型数据库, 主机断电时数据全部丢失。
-
key同时过期会造成Redis数据库的“雪崩”,容易把整个服务搞垮。
二、Redis安装
这里以windows系统为例:
Redis 支持 32 位和 64 位。这个需要根据操作系统的实际情况选择,这里我们下载64bit。
Redis-x64-5.0.10.msi安装到 自己的windows。
注意:把 redis 的路径加到系统的环境变量里
然后就可以使用客户端连接
redis-cli -h localhost -p 6379
三、Redis配置
找到安装目录下的配置文件redis.windows-service.conf,修改配置文件实现如下需求。
- 配置密码
搜索requirepass
设置密码
重启redis服务(任务管理器)
使用密码连接
redis-cli -h localhost -p 6379
>auth ****
>ping
- 配置远程登录
注释 bind 127.0.0.1
取消保护模式 protected-mode no
重启redis服务(在任务管理器中操作),如下:
模拟远程连接
完成!
四、Redis的通用命令
redis默认有16个 数据库(0-15)
select 3 切换到数据库3
info 查看redis服务的信息
info replication查看主从复制的状况
keys * 查看所有的key, 生产环境中不使用
可能阻塞redis
查看key的数据类型
type key1
key 是否存在
exists key1
删除一个key
del key1
重命名
rename key key1
清空数据库
flushdb/flushall
五、Redis的五种类型以及python实现
1、String类型
k e y − − > 字 符 串 / 数 值 key-->字符串/数值 key−−>字符串/数值
- key 不宜过长,占用内存,也不宜过短,可读性差
如:user:lauf - 值,为字符串或者数值,最多存储512M
数据操作
- 设置key-value
>set name jack
>mset name jack age 23 addr China
>append key val 追加
python实现
import redis
r=redis.Redis(host="localhost",port=6379,db=0)
r.set("name","jack")
r.mset({"name":"jack","age":23,"hobby":"football"})
- 获取key的值
get name
mget name age hobby
python实现
r.get("name") #返回字节串
r.mget("name","age","hobby") #返回值列表
- 设置key时,设置过期时间
#10s后过期
set name jack ex 10
#不存在时,设置key
set name jack nx
python实现
r.set("name","jack",ex=10)
r.set("name","666",nx=True)
- 获取字符串值的长度
strlen name
python实现
r.strlen("name")--->int
- 获取字符串的分片
set name jack
getrange name 0 1 #包含1
-->ja
python实现
r.set("name","jack")
r.getrange("name",0,1)
-->分片的字节串b'ja'
- 设置字符串的片段值
set name beikehan
setrange name 1 oo
-->bookehan
python实现
r.setrange("name",1,"oo")
- 数值加1、减1
set age 23
incr age 只能整型数值
-->24
decr age
-->23
- 数值加5、减5
set age 10
incrby age 5 只能整形
-->15
decrby age 5
-->10
incrbyfloat age 1.3 转为字符串
incrbyfloat age -1.2
字符串的使用场景
- 作为缓存
- 并发计数,点赞、秒杀
- 带有效期的验证码,过期自动删除
练习:基于django实现验证码的生成与存储
- 创建一个虚拟环境myenv,保证不会污染自己的默认环境
- 创建一个django项目,命名test_sms_code
- 配置项目的模板、静态文件等
- 配置路由,编写视图
设置过期时间
#1 10s过期
set name jack ex 10
#2
set name jack
expire name 10 -->10s
pexpire name 10 -->10ms
#查看多久过期
ttl name
-->返回-2 key不存在
-->返回-1 key存在,但没有过期时间
-->返回具体时间,剩余过期时间
#设置永不过期
persist name
2、List类型
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
类似: {name:[1,2,3,4,5,6,]}
插入列表
# 头插法
lpush key val1 val2 ...
127.0.0.1:6379> lpush numbers 1 2 3
(integer) 3
# 尾插法
127.0.0.1:6379> rpush numbers 8 9 0
(integer) 6
更新列表
# 修改某下标的值
lset key index val
127.0.0.1:6379> lset numbers 5 10 # 注意: redis中下标也是从0开始
OK
删除列表
# 头删法
lpop key # 删除第一个值, 并立即返回该值
127.0.0.1:6379> lpop numbers
"3"
# 尾删法
rpop key # 删除最后一个值, 并立即返回
127.0.0.1:6379> rpop numbers
"10"
#列表为空时,阻塞的删除
blpop mylist 10
brpop mylist 10
# 删除指定的值
lrem key count value # 返回的是删除的个数
127.0.0.1:6379>lrem numbers 0 2 # 删除所有值为2的元素
(integer) 4
127.0.0.1:6379>lrem numbers -2 1 # 从表尾开始删除2个值为1的元素
(integer) 2
127.0.0.1:6379> lrem numbers 2 1 # 从表头开始删除2个值为1的元素
(integer) 2
# 截取数据
ltrim key start stop
127.0.0.1:6379> ltrim numbers 2 5 # 保留下标为 【2,5】之间的所有元素,删除其余元素
OK
查询列表
lrange key start stop # 返回指定区间内的内容
127.0.0.1:6379> lrange numbers 0 -1
1) "3"
2) "2"
3) "1"
llen key #获取列表的长度
3、Hash类型
Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储字典数据。
插入哈希
# 设置单个 hset key field value
127.0.0.1:6379> hset user:123 name jack
(integer) 1
# 设置多个 hmset key field value [field2 value2] # 同时将多个 field-value (域-值)对设置到哈希表中;
#键和字段存在时,属于更新
127.0.0.1:6379> hmset user:123 name xiaomi age 23 gender man # 存储用户123的个人信息{'name': 'xiaomi', 'age': 23, 'gender': '男'}
(integer) 3
hincrby key field increment # 为哈希表 key 中的指定字段的整数值加上增量
127.0.0.1:6379> hincrby user:123 age 5 # 用户123的年龄加5岁
(integer) 24
查询哈希
hget key field #指定字段的值
127.0.0.1:6379> hget user:123 name
"xiaomi"
hgetall key # 获取所有字段和值
127.0.0.1:6379> hgetall user:123
1) "name"
2) "xiaomi"
3) "age"
4) "24"
5) "gender"
6) "man"
hkeys key #获取所有的字段
hvals key #获取所有的值
删除哈希
hdel key field1 [field2] # 删除一个或多个哈希字段, 返回删除的个数
127.0.0.1:6379> hdel user:123 gender # 用户123的性别
(integer) 1
4、Set类型
Set 是 String 类型的无序的容器结构。集合成员是唯一的,不能出现重复的数据。
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
插入集合
sadd key member1 [member2] # 向集合添加一个或多个成员
127.0.0.1:6379> sadd workers tom lucy jack
(integer) 3
删除集合
srem key member1 [member2] # 移除集合中一个或多个成员
127.0.0.1:6379> srem workers tom
(integer) 1
查询集合
scard key # 获取集合的成员数
127.0.0.1:6379> scard workers
(integer) 3
smembers key # 返回集合中的所有成员
127.0.0.1:6379> smembers workers
1) "tom"
2) "jack"
sismember workers tom # 判断是否集合中的成员
5、Zset类型
它是 String 类型元素的有序集合,每个元素唯一且都会关联一个 double 类型的分值,根据分值来为集合中的成员从小到大排序。
插入有序集合
# zadd key score1 member1 [score2 member2] # 向有序集合添加一个或多个成员,或者更新已存在成员的分数
127.0.0.1:6379> zadd salary 10000 Jim 8000 Tom 12000 JiMi 10000 Hake
(integer) 1
删除有序集合
zrem key member [member ...] # 移除有序集合中的一个或多个成员
127.0.0.1:6379> zrem salary Hake # 删除员工Hake
(integer) 1
# zremrangebyrank key start stop # 根据排名区间【0,3】 删除成员
127.0.0.1:6379> zremrangebyrank salary 1 2
(integer) 2
127.0.0.1:6379> zrange salary 0 -1
1) "dandan"
zremrangebyscore key min max # 根据分数区间【10,30】删除成员
127.0.0.1:6379> zremrangebyscore salary 10 30
(integer) 2
127.0.0.1:6379> zrange salary 0 -1
1) "liuyang"
2) "dandan"
更新有序集合
zincrby key increment member # 对指定成员的分数加上增量 increment
127.0.0.1:6379> zincrby salary 300 Jim # 给员工Jim涨300元薪资
"10300"
查询有序集合
zcard key #有序集合的所有成员数
127.0.0.1:6379> zcard salary # 查询所有成员
(integer) 4
zcount key min max # 统计在指定分数区间的成员数
127.0.0.1:6379> zcount salary (8000 10000 # 统计所有 8000 < score <= 10000 的成员数量
(integer) 0
zrank key member # 返回指定成员的排名
127.0.0.1:6379> zrank salary Tom # 根据分值从小到大排序,从0开始
(integer) 0
zrevrank key member #分值降序排序后的 排名
127.0.0.1:6379> zrevrank salary Tom #
(integer) 2
zscore key member # 返回成员的分数值
127.0.0.1:6379> zscore salary Tom # 查询Tom的薪资
"8000"
zrange key start stop [WITHSCORES] # 返回有序集合指定索引区间内的成员
127.0.0.1:6379> zrange salary 0 -1 # 查询所有的员工
1) "Tom"
2) "Jim"
127.0.0.1:6379> zrange salary 0 -1 withscores # 查询所有员工以及对应得薪资
1) "Tom"
2) "8000"
3) "Jim"
4) "10300"
zrevrange key start stop [WITHSCORES] # 分值降序后获取索引区间的成员
127.0.0.1:6379> zrevrange salary 0 -1 # 查询所有的员工,按照薪资降序展示
1) "JiMi"
2) "Jim"
3) "Tom"
127.0.0.1:6379> zrevrange salary 0 -1 withscores # 查询所有员工以及对应得薪资,按照薪资降序展示
1) "JiMi"
2) "12000"
3) "Jim"
4) "10300"
5) "Tom"
6) "8000"
# zrangebyscore key min max [WITHSCORES] [LIMIT] # 返回指定分数区间内的成员
127.0.0.1:6379> zrangebyscore salary 8000 20000 # 查询 薪资在8000到20000之间的所有员工
1) "Tom"
2) "Hake"
3) "Jim"
4) "JiMi"
# limit 进行分割, 从第二个数据开始
127.0.0.1:6379> zrangebyscore salary 8000 20000 limit 2 1 withscores #查询 薪资在8000到20000之间的所有员工以及对应的薪资,并对结果分页,每页显示1条数据,第3页
1) "Jim"
2) "10300"
zrevrangebyscore key max min [withscores] # 返回有序集中指定分数区间内的成员,分数从高到低排序
127.0.0.1:6379> zrevrangebyscore salary 20000 8000 # 查询 薪资在8000到20000之间的所有员工,按照薪资降序展示
1) "JiMi"
2) "Jim"
3) "Tom"
127.0.0.1:6379> zrevrangebyscore salary 20000 8000 limit 2 1 withscores #查询薪资在8000到20000之间的所有员工以及对应的薪资,按照薪资降序展示,并对结果分页,每页显示1条数据,第3页
1) "Tom"
2) "8000"
六、分页
limit (page-1)*n n: page代表取第几页,n代表每页数量
1-8
第1页 1 2 limit 0 2
第2页 3 4 limit 2 2
第3页 5 6 limit 4 2
第4页 7 8 limit 6 2
总结
以上就是今天要讲的内容,本文仅仅简单介绍了redis的使用,而redis还有更多的使用方法,有兴趣的同学们还可以问下度娘哦!