Redis学习笔记

一、什么是nosql

(1)NoSQL的基本说明:

NoSQL(NoSQL = Not Only SQL),意味反sql运动,是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。它指的是非关系型的数据库。

(2)兴起的原因:

随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模高并发的sns类型的web2.o纯动态网站已经显得力不从心,暴露了很多难以克服的 问题,而非关系型的数据库则由于本身的特点得到了非常迅速的发展。

(3)特点:

优点: 

高并发读写的性能 

大数据量的扩展(分布式存储) 

配置简单 

灵活、高效的操作与数据模型 

低廉的成本 


不足之处: 

没有统一的标准 

没有正式的官方支持 

各种产品还不算成熟

(4)常见的nosql产品

新浪微博      Redis

Google       Bigtable

Amazon       SimpleDB

淘宝数据平台    Tair

优酷视频      MongoDB

飞信空间      HandlerSocket

视觉中国网站   MongoDB

二、redis的基本介绍

Redis是Remote Dictionary Server(远程数据服务)的缩写 由意大利人 antirez(Salvatore Sanfilippo)开发的一款 内存高速缓存数据库

redis是一个开源的,先进的key-value存储。它通常被称为数据结构服务器,因为键可以包含字符串,哈希,链表,集合有序集合

(1)架构方式:c/s   客户端和服务器

(2)memcache存储数据的位置:内存中。


redis:可以存储到内存中,可以把数据同步 到硬盘中,达到数据的存储持久化。


(3)memcache存储数据类型的格式:键值对。没有行和列的概念

redis:数据存储是,键值对存储,只不过存储的值的类型比较丰富,有五种类型,string(字符串),hash(哈希),list(链表),set(集合)zset(有序集合)


基本介绍:

(1)Redis是一个Key-Value存储系统。 

(2)它支持存储的value类型很多,包括string(字符串)list(链表)set(集合)Zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集和并集及更丰富的操作、Redis支持各种不同方式的排序。 

(3)为了保证效率数据都是缓存在内存中,它也可以周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件。 

(4)提供的API语言包括:C、C++、C#、Clojure、Common、Lisp、Erlang、Haskell、Java、Javascript、Lua、Objective-C、Perl、PHP、Python、Ruby、Scala、Go、Tcl

(5) Redis的默认端口号:6379

三、redis的安装

Redis对于Linux是官方支持的,安装和使用没有什么好说的,普通使用按照官方指导,5分钟以内就能搞定。详情请参考:

http://redis.io/download 

Redis官方是不支持windows的,只是 Microsoft Open Tech group 在 GitHub上开发了一个Win64的版本,项目地址是:

https://github.com/MSOpenTech/redis/releases

打开以后,可以直接使用浏览器下载,或者Git克隆。

安装完成之后,启动redis服务 打开redis客户端 开始使用redis客户端进行下面的redis命令学习

四、redis的数据类型

string(字符串):类似于memcache里面的数据存储方式

key values    demo: name  王刚 

redis1.gif


hash(哈希):类似于关系型数据库里面的行,

也是键值对,值里面又有键值对。

key  key1 values ke2 values key3 values  demo: user1  name=>zhangsan age=>21 email=>zhangsan@163.com height=>198

redis2.gif


list(链表):可以模拟队列和栈。数据存储是有顺序的。

队列:先进先出。

栈:先进后出。

存储数据时,如果从头部添加,则模拟是栈。因为我们取数据时,是从头部到尾部取出的(从头部开始取数据,一直取到尾部)。如果从尾部添加数据,则模拟的是队列,先进先出

redis3.gif


set(集合)

集合名称 集合里面的内容,内容存储是无序的    demo:  myfriend  张无忌 乔峰 杨过 注意:张无忌 乔峰 杨过是没有顺序的

redis4.gif


zset(有序集合) 集合里面的内容是有序的。

集合名称 集合里面的内容,内容是由编号的      demo:  myfriend 1张无忌 2乔峰 3杨过

redis5.gif

五、redis的数据类型讲解相关命令

1、string类型

string是最简单的类型,一个 key对应一个value,string类型是二进制安全的。Redis的 string可以包含任何数据,比如jpg图片或者序列化的对象。 

(1)set

设置键 值 

语法:set  键名称  值 

例如:我们添加一个name="zyl"的键值对。  demo: set name zyl  

如果重新设置name则直接覆盖上一次的name。 

(2)get

获取key对应的string值,如果key不存在返回 nil。

语法:get 键值    demo: get name   会得到zyl

(3)setnx 

设置键时,先判断一下该键是否存在,如果key已经存在,返回0,nx是not exist的意思。 

若键已经存在,则设置不成功,返回0  demo: setnx name 'wzyl'  返回:0 设置失败 因为上面第一次的时候已设置过name的值

(4)setex 

设置key对应的值为string类型的value,并指定此键值对应的有效期。 

语法:setex 名称 有效期   值 

例如:我们添加一个color = red的键值对,并指定有效期为5秒。demo: setex color 5 red  五秒钟以内会取出color的值 5秒钟之后get color则得到nil

(5)setrange 

替换字符串中某些字符 

语法:setrange    键名称    开始替换的序号   替换为的内容 

例如:我们希望将hanguo的sohu邮箱替换为qq.com邮箱     

demo: 创建一个email set email hanguo@souhu.com 将souhu.com替换为qq.com  setrange email 7 qq.com.cn  

(6)mset 

一次设置多个key的值,成功返回ok表示所有的值都设置了,失败返回0表示没有任何值被设置。 

语法: 

mset  名称1  值1  名称2  值2    demo: mset name zhangsan age 13  

(7)msetnx 

一次设置多个key的值,成功返回ok表示所有的值都设置了,失败返回0表示没有任何值被设置,但是不会覆盖已经存在的key。

(8)getset 

设置key的值,并返回key的旧值。(设置新值,获取旧值)  demo: getset name zz

(9)getrange 

获取key的value值的范围内的子字符串 

getrange name 0 3     demo: getrange name 0 3 获取name的值的前四个字符  0 3下标从0开始 0 1 2 3所以是获取到了四个字符

(10)mget 

一次获取多个key的值,如果对应key不存在则对应返回nil。 demo: mget name age sex    

(11)incr 

对key的值做加加操作,并返回新的值。 demo: incr age  输出age+1之后的值

incrby 

同incr类似,加指定值,key不存在时候会设置key,并认为原来的value是0。  

demo: incrby age 10 输出原来age的值+10之后的值,比如说原来age的值为20 那么+10之后的值就是30 也就是会输出30

(12)decr 

对key的值做减减操作。   同上面的incr一样 只不过这个是减

decrby 

同decr类似,减指定值   同上面的incrby一样 只不过这个是减

(13)append

给指定key的字符串追加value,返回新字符串值的长度。  

14strlen

取指定keyvalue值的长度。  demo: strlen name

2、hashes类型

Redis hash是一个string类型的field和value的映射表。它的添加、删除操作都是0(1)(平均)。hash特别适合用于存储对象。

相较于将对象的每个字段存成单个string类型。将一个对象存储在hash类型中会占用更少的内存,并且可以更方便的存取整个对象。一个哈希数据相当于mysql的一条记录。 

(1)hset 

设置hash field为指定值,如果 key不存在,则先创建。 

语法: 

hset  哈希名称  字段名称   值    demo: hset myhash1 name zyl  //创建一个哈希名称为myhash1 字段名称为name 值为zyl的哈希数据

(2)hget

取出hash field的值。语法:hget 哈希名称  字段名称   demo: hget myhash1 name  

(3)hsetnx 

设置hash field为指定值,如果key不存在,则先创建,如果存在则返回0。 

(4)hmset 

同时设置hash的多个field

语法:hmset 哈希名称  field1  value1 field2 value2  demo: hmset student1 name xiaowang age 12 

(5)hmget 

获取全部指定的hash field。 

语法:hmget 哈希名称 field1 field2    demo: hmget student1 name age //接着上面的hmset看的话 这里输出 xiaowang 12

(6)hincrby 

指定的 hash  field加上给定的值。     demo: hincrby student1 age 3  //给名字为student1的哈希的age字段在原有基础上加3

(7)hexists 

测试指定的 field是否存在。          demo: hexists student1 name

(8)hlen 

返回指定hash的field数量。           demo: hlen student1 

(9)hdel 

删除指定hash的field

语法:hdel 哈希名 field            demo: hdel student1 age

(10)hkeys 

返回hash的所有field               demo: hkeys student1  

(11)hvals 

返回hash的所有 value。             demo: hvals student1

(12)hgetall 

获取某个hash中全部的field及value      demo: hgetall student1 

3、lists类型及操作(集合) 

list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等,操作中key 理解为链表的名字。

redis的list类型其实就是一个每个子元素都是string 类型的双向链表。我们可以通过push、pop操作从链表的头部或者尾部

添加删除元素,这样list即可以作为栈,又可以作为队列。 

(1)lpush 

在key对应list的头部添加字符串元素。

语法:lpush 链表名称  值内容    

demo: lpush list1 one 

demo: lpush list1 two

demo: lpush list1 three 

可以使用lrange输出  demo: lrange list1 0 -1   //0代表头部,-1代表尾部。 最终输出: three two one 可以看到最后添加的three,但是three确是最先输出的。由此可见这是栈  即lpush模拟的是栈

(2)lrange

获取链表里面的值,语法:lrange 链表名称  0 -1 

注意0 和 -1 表示取值范围,从头部到尾部。

(3)rpush 

在key对应list的尾部添加字符串元素。

语法:rpush 链表名称  值内容

demo: rpush list2 hello

demo: rpush list2 world

demo: rpush list2 welcome

使用lrange输出:  lrange list2 0 -1   //输出结果: hello world welcome 由此看见最先进入的hello依然是最先出来 先进先出的特性。。所以这里是模拟的队列 即rpush模拟的是队列

(3)linsert 

在key对应list的特定位置前或后添加字符串。  demo: linsert list1 before test zyl //在test前面添加一个字符串为zyl

(4)lset 

设置list中指定下标的元素值。注:下标从0开始计算  demo: lset list1 0 indexs //将list1中的第一个元素的值设为indexs 如果list1中有第一个元素值的话  那么此操作会将之前第一个元素的值覆盖掉

(5)lrem 

从key对应list中删除n个和value相同的元素。(n<0从尾删除,n=0全部删除)

demo: lrem list1 2 one //从list1中 删除2个one

(6)ltrim 

保留指定key的值范围内的数据(0是头部的第一个列表元素)。 demo: ltrim list1 1 2  //将list1中的第二个和第三个元素保留

(7)lpop 

从list的头部删除元素,并返回删除元素。  demo: lpop list1  //输出 列表中被删除的头部元素

(8)rpop 

从 list的尾部删除元素,并返回删除元素。 demo: lrpop list1  //输出 列表中被删除的尾部元素 

(9)rpoplpush 

从第一个list的尾部移除元素并添加到第二个list的头部。  demo: rpoplpush list1 list2

(10)lindex(下标从0开始 0表示第一个元素) 

返回名称为key的list中 index位置的元素。   demo: lindex list1 1 //从list1的头部获取下标索引为1的元素值 下标为1 就是获取第二个有元素  为0是获取第一个

(11)llen 

返回key对应list的长度。  demo: llen list1  //输出list1中所有元素的总数量

4、sets类型及操作 

set是集合,它是string类型的无序集合。set是通过hash table实现的、添加、删除和查找的复杂度都是0(1)。对集合我们可以取并集、交集、差集。通过这些操作我们可以实现sns中的好友推荐和blog的tag功能。

(1)sadd 

向名称为key 的set中添加元素。 

语法:sadd 集合名   元素   

demo: sadd myset1 nihao   

(2)smembers 获取集合中内容。

语法:smembers 集合名称    demo: smembers myset1

(3)sinter

返回所有给定key的交集(获取给定集合中的交集->取指定集合中的交集元素)

demo: sadd myset1 nihao    sadd myset1 hello    sadd myset1 one    sadd myset2 hello    sadd myset2 two

    sinter myset1 myset2 //output: hello  因为hello元素在myset1集合中和myset2集合中都出现过 所以hello是myset1 myset2交集元素 

(4)sdiff 

返回所有给定key与第一个key的差集。 

这里我们接着上面(3)sinter插入的数据演示

demo: sdiff myset1 myset2  //output: one nihao两个元素 即返回的是myset1集合中的元素在myset2集合中不存在的元素,这里和php的的array_diff()函数是一样的

(5)sunion 

返回所有给定key的并集

demo: sadd myset1 hello  sadd myset1 word  sadd myset2 hello  sadd myset2 php

sunion myset1 myset2  //output: hello world php

(6)srem 

删除名称为key的set中的元素  demo: srem myset1 hello

(7)spop 

随机返回并删除名称为key的 set中一个元素  demo: spop myset1

(8)sdiffstore 

返回所有给定key与第一个key的差集,并将结果存为另一个key。 

语法:sdiffstore 新的集合  集合1   集合2 

(9)sinterstore 

返回所有给定key的交集,并将结果存为另一个key

(10)sunionstore 

返回所有给定key的并集。

(11)smove 

从第一个key对应的set中移除member并添加到第二个对应的set中。

(12)scard 

返回名称为key的set的元素个数。 demo: scard myset1  //output: myset1集合中元素的总数量

(13)sismember 

测试member是否是名称为key的中的元素 demo: sismember myset1 nihao

(14)srandmember 

随机返回名称为key的set的一个元素,但不删除元素   demo: srandmember myset1

5、sorted sets类型及操作(有序集合)

(1)zadd 

向名称为key的zset中添加元素。如果该元素存在,则更新其顺序。

语法:zadd 集合名  序号  内容

demo: zadd zset1 1 one  zadd zset1 2 two

(2)zrange

获取有序集合中的内容

demo: zadd zset1 1 web  zadd zset1 2 php  zrange zset1 0 -1 [withscores] //output: 没有设置withscores参数情况下输出: web php  设置withscores参数情况下输出:web 1 php 2 设置了withscores后会将当前序号一起显示出来

(3)zrem 

删除名称为key的zset中的元素member  demo: zrem zset1 php

(4)zincrby 

如果在名称为key的zset中已经存在元素member,则该元素的score增加increment否则向该集合中添加该元素,其score的值为increment。 

(5)zrank 

返回名称为key的zset中member元素的排名(按score从小到大排序)即下标。

(6)zrevrank 

返回名称为key的zset中member元素的排名(按score从大到小排序)即下标。

(7)zrevrange 

返回名称为key的zset(按score从大到小顺序)中的index从start到end的所有元素。

(8)zrangebyscore 

返回集合中score在给定区间的元素

(9)zcount 

返回集合中score在给定区间的数量。

(10)zcard 

返回集合中元素的个数 

(11)zremrangebyrank 

删除集合中排名在给定区间的元素。

(12)zremrangebyscore 

删除集合中score在给定区间的元素。 

6、redis常用命令

redis提供了丰富的命令对数据库和各种数据库类型进行操作,这些命令可以在linux终端使用。 

1、键值相关的命令 

(1)keys

返回满足给定参数的所有key

用表达式*,代表取出所有的key

demo: keys *    //输出: redis中所有已存在的key

demo: key2 my*   //输出: 以my开头的key

(2)exists

确认一个key是否存在。  demo: exists name  

(3)expire

设置一个key的过期时间  demo: expire name 10  //将name这个key设置有效期为10秒钟 10秒钟后name将自动删除

ttl name //查看该key还剩余多长时间自动过期

(4)move:

将当前数据库中的key转移到其它数据库中。

(5)persist

移除给定key的过期时间  demo: persist name

(6)randomkey 

随机返回key空间的一个key

(7)rename

重命名key   demo: rename name myname //将name这个key重命名为myname

(8)type:返回值的类型     demo: type myname

2、服务器相关命令

(1)select

选择数据库。redis数据库编号从0-15,我们可以选择任意一个数据库来进行数据的存取。 demo: select 5

当选择16时,报错,说明没有编号为16的这个数据库。

(2)quit

退出连接 

(3)dbsize 

返回当前数据库中key的数目  demo: dbsize

(4)info

获取服务器的信息和统计。   demo: info

(5)config get

获取参数的配置。 

本例中我们获取了dir这个参数配置的值  demo: config get dir

如果想获取全部参数的配置只需要执行”config get *”即可将全部的值都显示出来  demo: config get *

(6)flushdb 

删除当前选择数据库中的所有key  demo: flushdb

(7)flushall 

删除所有数据库中的所有的 key   demo: flushall

六、redis的安全性(Linux下)

设置客户端连接后进行任何其他操作前需要使用的密码。 

注意:因为 redis速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行150k(15万)次的密码尝试,这意味着你需要指定非常非常强大的密码来防止暴力破解。 

(1)设置密码的方式,打开redis的配置文件。(redis.conf)

#requirepass 设置的密码

比如:requirepass zyl  注意: requirepass前面的#号需要删除掉密码才能生效

设置完密码后,redis服务要重启。

(2)设置完成密码后,客户端登录方式:

第一种方式:登录后,执行 auth设置的密码 后才能操作,否则不能任何操作。 demo:  auth zyl

第二种方式:在登录时,输入密码

/usr/local/redis/bin/redis-cli  –a  设置的密码

七、redis的持久化机制

redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘来保证持久化。 

redis支持两种持久化方式: 


(1)snapshotting(快照)默认方式 

快照是默认的持久化方式。这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb.可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key修改就自动做快照。

demo: save 900 1     //900秒内如果超过1个key被修改,则发起快照保存

demo: save 300 10    //300秒内如果超过10个key被修改,则发起快照保存

上面中900 300 指的是"秒数",1 10 指的是"change次数" change在程序中即是修改的意思


快照方式的缺点:

由于快照方式是在一定间隔做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。


(2)append-only file(缩写 aof)的方式

aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。

aof方式 

当然由于os会在内核中缓存write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。 

可以通过配置文件告诉reids我们想要通过fsync函数强制os写入到磁盘的时机。

可在配置文件配置如下几种方式:


appendonlyyes //启用aof持久化方式


#appendfsync always    //收到写命令就立即写入磁盘,最慢,但是保证完全的持久化

appendfsync everyysec  //每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中

#appendfsync no      //完全依赖os,性能最好,持久化没保证


八、redis配置文件常用的项


daemonize如果需要在后台运行,把该项改为yes

pidfile:配置多个pid的地址 默认在/var/run/redis.pid

bind:绑定ip,设置后只接受来自该ip的请求。 

port:监听端口,默认为6379

timeout:设置客户端连接时的超时时间,单位为秒。 

logfile:配置log文件的地址。 

databases:设置数据库的个数,默认使用的数据库为0

sava:设置redis进行数据库镜像的频率。 

rdbcompression:在进行镜像备份时,是否进行压缩。 

Dbfilename:镜像备份文件的文件名。 

Dir:数据库镜像备份的文件放置路径。 

Slaveof:设置数据库为其他数据库的从数据库。 

Masterauth:主数据库连接需要的密码验证。 

Requirepass:设置登录时需要使用的密码。 

Maxclients:限制同时连接的客户数量 

Maxmemory:设置redis能够使用的最大内存。 

Appendonly:开启append only模式。

九、php支持redis

(1)下载扩展,在下载扩展时要注意,和php的版本要兼容。

(2)把对应的扩展拷贝到,php的安装目录ext目录下面。

(3)打开php.ini文件,引入扩展文件。 

(4)重启apache进行测试,写一个php测试文件,运行phpinfo()函数测试 搜索一下看看有没有redis扩展


可参考以下网址给php5.6版本安装redis扩展(windows下)

http://www.cnblogs.com/aajonas/p/6109446.html

5)php操控redis的基本使用

$redis  = new redis();
$redis->connect('127.0.0.1',6379);   //127.0.0.1 redis服务器的ip  6379redis默认端口号

//$redis->auth('zyl');  //redis密码(如果在redis配置文件中设置了密码的话 需要进行这一步的密码认证)

$redis->set('name','xiaofang');  //存储一个key为name  值是xiaofang

var_dump($redis->get('name')); //获取刚刚存入的key为name的值  output: xiaofang


声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。

小周博客
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

精彩评论

全部回复 0人评论 7,777人参与

loading