帮助手册
https://github.com/phpredis/phpredis#rpop
一、Redis 简介
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。
Redis 与其他 key - value 缓存产品有以下三个特点:
1.Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
2.Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
3.Redis支持数据的备份,即master-slave模式的数据备份。
二、Redis 优势
1. 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
2. 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
3. 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
4. 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
三、Redis与其他key-value存储有什么不同?
1. Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
2. Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
四、Redis 安装
下载安装包安装文件
使用命令进入目录
redis-server.exe redis.windows.conf 不要关闭这一屏 也不要结束
redis-cli.exe 从新起一个页面
将redis加入到windows的服务中(service和loglevel前都是两个-)开机自启动
有可能是:redis-server --service-install redis.windows-service.conf --loglevel verbose
也有可能是:
redis-server --service-install redis.windows.conf
再次 win+R,运行 services.msc
找到Redis,右键启动,如图。
图形界面工具
三、Redis 数据类型
掌握redis有5中数据类型 ,能够通过项目的需求使用不同的类型 ,用的比较多的类型为
String hash list zset[带分数的]
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(
Sort set:有序集合)。
数据类型 |
存储的值 |
读写能力 |
String |
可以是字符串、整数统称为元素 |
对字符串的操作 对整数类型的加减 |
List |
一个序列集合且每个节点都包好了一个元素 |
序列两端推入,或弹出元素,修检、查找或移除元素 |
Set |
各不相同的元素 |
从集合中插入或删除元素 |
Hash |
有key和value的散列组, |
按照key进行添加删除 |
zset |
带分数的score-value有序集合 |
集合中插入按照分数进行查找 |
(一)String(字符串)
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
实例
注意:一个键最大能存储512MB。
赋值 SET key value [EX seconds] [PX milliseconds] [NX|XX]
> set name zhagnsan
mset age 18 sex 男 设置多个
mset name zhangsan age 18 sex nan
取值 GET key
get name
mget number name 获取多个值
mget name age sex
先获取在设置 getset name zhangsan将给定key设置为value的值,并返回key的旧值
删除 del name 删除key的值 如果有执行成功返回1 失败返回0
del name
加一 incr number 指定key的值自增1
set number 1 incr number
减一 decr number 指定key的值减1
decr number
指定加值 incrby number 5 将key所存储的值加上给定的增加值
incrby number 10
指定减值 decrby number 3 将key所存储的值加上给定的减值
decrby number 2
拼凑(追加) append a 123
append number hellow
(二)Hash(哈希)
redis hash 是一个键值(key=>value)对集合。
redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
实例
DEL runoob 用于删除前面测试用过的 key,不然会报错:(error) WRONGTYPE Operation agai
实例中我们使用了 Redis HMSET, HGET 命令,HMSET 设置了两个 field=>value 对, HGET 获取对应 field 对应的 value。
每个 hash 可以存储 232 -1 键值对(40多亿)。
赋值 hset hash1 name zhangsan 设置给定的key的value
hset 1802A name zhangsan
hmset hash2 name lisi age 18 sex nan 设置多个
hmset 1803A name zhansan age 18 sex nan
取值 hget hash1 name 获取存储在哈希表中指定字段的值
hget 1802A sex
hmget hash2 name age sex 获取多个
hmget 1802A name sex
hgetall hash2 获取所有的
hgetall 1802A
删除 hdel hash2 name 删除指定的字段
hdel 1802A name
del hash2 删除指定所有
del 1803A
增加 hincrby hash1 age 5
hmset user1 name zhansan age 18 sex nan hgetall user1 hincrby user1 age 1
hexists hash1 age 查看哈希表 key 中,指定的字段是否存在。存放返回值 不存在返回0
hexists user1 sex
hlen hash1 获取哈希表中字段的数量
hlen user1
hkeys hash1 获取所有哈希表中的字段
hkeys user1
hvals hash1 获取哈希表中所有值
hvals user1
(三)List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
实例
列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。
两端添加 lpush mylist a b c 将一个或多个元素插入到列表头部
lpush mylist a b c d e
rpush mylist a b c 将一个或多个元素插入到列表尾部
rpush mylist2 1 2 3 4 5 6
查看 lrange mylist 0 3 获取列表指定范围内的元素
开始 结束 结束-1 为全部
lrange mylist 0 4 lrange mylist 0 -1
两端弹出 lpop mylsit 移除并获取列表的第一个值【从头删除】
lpop mylist
rpop mylsit 移除并获取列表的最后一个值【从尾删除】
rpop mylist
获取列表个数 llen mylist 获取列表的长度
llen mylist
仅当存【这个变量有的时候】在时才插入 lpushx mylist q 当mylist存在的时候,将p插入到头部【插入头部】
lpushx mylist nihao lpushx mylis nihao
仅当存在时才插入 rpushx mylist q 当mylist存在的时候,将p插入到尾部【插入尾部】
rpushx mylist abcd
删除 lrem mylist 2 a 删除 2个a
lrem mylist 1 abcd
Lrem list 3 2 删除3个2元素
在指定元素前【后】插入元素 linsert mylist before[after] b 11; 在b之后(之前)插入元素
linsert mylist after d abcde linsert mylist before d 1234
Rpoplpush mylist mylist2 从一个列表中弹出一个值压入到另一个列表中
rpoplpush mylist mylist2
(四)Set(集合)
Redis的Set是string类型的无序集合。 在set中存储的数据都是唯一的。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度。
实例
添加 sadd myset a b c
sadd myset a b c d
注:相同的值只能插入一个
删除 srem myset a b
srem myset a b
查看 smembers myset
smembers myset
是否存在 sismember myset a myset中a是否存在
sismember myset a sismember myset d
差集 sdiff myset1 myset
sdiff myset1 myset
交集 sinter myset1 myset2
sinter myset myset1
并集 sunion myset myset2
sunion myset myset1
长度 scard myset
scard myset1
随机返回成员 srandmember myset
差集存入变量 sdiffstore
sdiffstore myset2 myset1 myset
将myset1中的有的,但是myset中没有的数据插入到myset2当中去
交集存入变量 sinterstore
sinterstore myset3 myset1 myset
解释:myset1 和myset中都有的数据 存放进入myset3当中
并集存入变量 sunionstore
sunionstore myset4 myset1 myset
解释:求myset1 和 myset的并集存入到 myset4中
跟踪唯一,访问博客的ip地址存入到set中
注意:以上实例中 rabitmq 添加了两次,但根据集合内元素的唯一性,第二次插入的元素将被忽略。
集合中最大的成员数为 232 - 1(4294967295, 每个集合可存储40多亿个成员)。
(五)zset(sorted set:有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
zadd 添加 zrange 获取倒数的时候 zrevrange 获取正数的时候 zcount 按照分数段进行统计 zincrby 减分加分
添加 Zadd mysort 70 zhangsan 80 lisi 90 wangwu 100 zhaoliu 60 tianqi
zadd mysort 70 zhangsan 80 lisi 90 wangwu 100 zhaoliu 60 tianqi
解释:添加有序集合
存储效果
取值 zscore mysort zhangsan
zscore mysort zhangsan
解释:取出mysort中的张三的分数
Zcard mysort 成员数量
zcard mysort
获取mysort中的成员的数量
范围查找 zrange mysort 0 -1全部的内容 (从小到大)
zrange mysort 0 4
zrevrange mysort 0 3 查询 下标从0 到3(从大到小)
zrevrange mysort 0 3
删除 zrem mysort tianqi
zrem mysort tianqi
Zremrangebyscore mysort 80 100 删除80到100之间的分数
zremrangebyscore mysort -10 60
zremrangebyrank 按照下标的范围删除
zremrangebyrank mysort 0 2
zrem mysort zhangsan lis 删除指定字段
zrem mysort zhangsan lisi
删除张三和李四的分数
zrange mysort 0 -1 withscores 元素对应的分数
zrange mysort 0 -1 withscores
Zrangebyscore mysort 90 100 withscores
zrangebyscore mysort 90 100 withscores
查询90-100分之间的详细信息
zrangebyscore mysort 90 100
zincrby mysort 3 list 给list+3
zincrby mysort 10 feiyangyang
给沸羊羊+10分
zincrby mysort -3 list 给list-3
zincrby mysort -10 feiyangyang
给沸羊羊 -10 分
Zcount mysort 90 100 统计90到100之间有多少
zcount mysort 90 100
统计90分到100分之间的人数
课堂案例
1. 选取Redis合理的数据类型进行存储(10分)
2. 成绩录入功能完成(15分)
zadd mysort 90 zhangsa 95 lisi 98 zhaoliu 80 tianqi 70 wangwu 18 wamger 70 meiyangyang 100 xiyangyang 75 feiyangyang 50 lanyangyang 90 huitaoilang 70 xiaohuihui 40 daolang 80 hongtalang 30 jiaotailang
4. Redis中读取TOP10排行榜(10分)
zrevrange mysort 0 9 withscores
5. Redis中读取最差10排行榜(10分)
zrange mysort 0 9 withscores
6. Redis中读取成绩分布统计数据,如效果图(15分)
低于60分
得到低于60分的人
61-69分
zcount mysort 61 69
70-79分
zcount mysort 70 79
80分以上
zcount mysort 80 100
Key的通用操作
Type score1 判断redis的类型
type mysort type name
expire score1 100 设置score1的过期时间 [到过期时间删除该变量]
Ttl score 所剩的时间
ttl mylist
Exists email 判断是否存在,存在是1 不存在是 0
127.0.0.1:6379> exists name 127.0.0.1:6379> exists name1
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以秒为单位,返回 key 的剩余生存时间。
del email 删除元素
127.0.0.1:6379> del name
rename age ages 命名操作
查询所有的redis
keys * keys my*
select 3 选择数据库 后面跟数据库的名称
redis的事务
Redis 事务
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
· 批量操作在发送exec命令前被放入队列缓存。
· 收到 exec命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
· 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
一个事务从开始到执行会经历以下三个阶段:
· 开始事务。
· 命令入队。
· 执行事务。
开启事务 multi
执行 exec
回滚 discard
Redis的两种持久化
优势:值包含一个文件 可以压缩
缺点:出现down机数据会丢失
RDB方式 [以时间为节点定期写入] 默认的方式 在指定时间内将数据写入到磁盘当中
save 900 1 每900秒一个key发生变化时写入
save 300 10 每300秒10个key发生改变的时候写入
save 60 10000 每 60秒有1万个key发生改变时写入
写入到 目录下 dump.rdb
AOF方式
优势:数据安全 append追加数据 down机也不用担心
以日志的形式写入到磁盘当中,会记录所处理的每一个操作
修改配置文件appendonly no -》yes 修改为yes
appendfsync always 每次修改的时候写入,
#appendfsync everysec 每秒写入
# appendfsync no 不同步
laravel框架操作redis
简介
Redis 是一个开源的,高级键值对存储数据库。由于它包含 字符串 , 哈希 , 列表 , 集合 , 和 有序集合 这些数据类型,所以它通常被称为数据结构服务器。
在使用 Laravel 的 Redis 之前,你需要通过 Composer 安装 predis/predis 扩展包:
在项目中安装例如项目是day17 进入day17 进行安装
指令:
composer require predis/predis
控制器层代码:
建立与redis的连接
$redis= Redis::connection();//建立redis连接
字符串类型
设置数据
$redis->set('name','张三');//设置一个值为张三
批量设置数据
$arr=['name'=>'张三','age'=>'18','sex'=>'男'];//定义数组 $redis->mset($arr);//批量设置多个
获取数据
$redis->get('name');//获取redis中的数据
批量获取数据
$redis->mget(['name','age']);//批量获取多个
自加
$redis->set('count','0');//设置点击数为0 $redis->incr('count');//+1 操作
注意:一直会输出1
按照指定的值增加,比如说+10
$redis->set('count','0');//设置点击数为0 $redis->incrby('count',10);
自减
$redis->set('count','0');//设置点击数为0 $redis->decr('count');//自减
按照指定的值相减 -10
$redis->set('count','0');//设置点击数为0 $redis->decrby('count',10);//减去数值
优化 检测是否存着
if(!$redis->exists('count')){//如果没有设置 $redis->set('count','0');//设置点击数为0 } $redis->incr('count');//+1 操作
删除数据
$redis->del('count');//删除redis数据
追加
$redis->append('name','追加的内容');//追加指定的内容
哈希类型
添加数据
$redis->hset('1802A','user','张三');//设置hash类型的数据
添加多个
$redis->hmset('1802A',['user02'=>'李四','user03'=>'王五']);//批量设置多个
获取数据
$redis->hget('1802A','user');//获取数据
获取多个
print_r($redis->hmget('1802A',['user','user02','user03']));//批量获取多个
获取所有的数据
print_r($redis->hgetall('1802A'));
删除指定字段
$redis->hdel('1802A',['user']);//删除指定字段
删除所有的
$redis->del('1802A');//删除所有
检测字段是否存在
$redis->hexists('1802A','user02');
增加数值
$redis->hset('number','num1','10');//设置数据 $redis->hincrby('number','num1',5);//按照指定的值增长
list(列表)
从头插入数据
$redis->lpush('mylist',['1','2','3','4','5']);//从头部插入数据
从尾部插入数据
$redis->rpush('mylist',['a','b','c','d']);//从尾部插入
从头部删除
$redis->lpop('mylist');//从头部开始删除
从尾部删除
$redis->rpop('mylist');//从尾部删除
获取数据
print_r( $redis->lrange('mylist',0,-1));//获取所有的数据
在指定位置插入
$redis->linsert('mylist','before',5,'f');
从尾部弹出一个压如到另一个头部
$redis->rpoplpush('mylist1','mylist2'); //从列表的尾部弹出一个压入到另一个列表的头部
set类型
添加
$redis->sadd('myset',['192.168.2.2','192.168.2.3','192.168.2.4','192.168.2.5','192.168.2.5']);
删除
$redis->srem('myset','192.168.2.2');//删除元素
查看
print_r( $redis->smembers('myset'));
是否存在
var_dump( $redis->sismember('myset','192.168.2.3')); var_dump( $redis->sismember('myset','192.168.2.2'));
注意:有返回1 没有返回0
长度
var_dump ($redis->scard('myset'));//检测长度
差集
print_r( $redis->sdiff(['myset','myset1']));//差集 前面的有的,后面没有
交集
print_r($redis->sinter(['myset','myset1']));//交集 都有的
并集
print_r($redis->sunion(['myset','myset1']));//并集 和在一起的
返回一个随机成员
控制器代码
if(!$redis->exists('student')){//检测是否存在 echo "12"; $data= Student::getAll()->toArray();//将对象转化为数组 $student=[];//声明一个数组 foreach($data as $item){ $student[]=$item['name']; } $redis->sadd('student',$student);//添加数据 } var_dump( $redis->srandmember('student'));//返回一个随机成员
模型层
protected $table="student"; //获取指字段的数据 addSelect 是指定字段 public static function getAll(){ return self::addSelect('name')->where('class1','1802A')->get();//获取所有的数据 }
有序集合 zset
添加
$redis->zadd('score',['张三'=>'80','李四'=>'90','王五'=>'100','赵六'=>'70','夏羊羊'=>'95','美羊羊'=>'90','灰太狼'=>'90']);
取值
//某个人多少分 echo $redis->zscore('score','王五'); //成员个数 echo $redis->zcard('score');
删除
$redis->zrem('score','赵六');//删除
前几名 从大到小得到数据
print_r( $redis->zrevrange('score',0,4,'withscores'));//获取前五名的成绩
后几名 从小到大得到数据
print_r( $redis->zrange('score',0,4,'withscores'));//获取后五名的成绩
分数段统计
print_r( $redis->zcount('score',90,100));//统计90-100分之间的人数
加分数
$redis->zincrby('score','5','张三');//给某一个具体的成员加分
//使用redis实现数