mysql---
select * from table where xx;
insert into table(name1,name2..) values(value1,value2);
delete from table where id=2;
update table set name='张三' where id=1;

nosql ---
特点:非关系型、分布式(主从复制、主从分离更容易)。
优势:处理超大量的数据、运行在便宜的PC服务器集群上、击碎了性能瓶颈。

——————————————————————————————————————————————————————————————————————————————————————————————————————————————————
redis:key--value存储。通常被称为数据结构服务器。

五种数据类型

1.string类型:最简单的类型,一个key对应一个value,可存储任何类型。以二进制方式存储,可以存储图片.序列化的对象等。
方法
--set --- 如:>set name zhangsan 设置name的为zhangsan的键值对。再次设置会被覆盖。即只能存在一个唯一的key。
--get --- 获取设置的key值。
--setnx(set not exist设置不存在的值) ---->格式:setnx key value 会判断key是否存在,存在则不设置,返回0,不存在则设置,返回1。
--setex(指定键的有效期) --> 格式 setex name 10 zhangsan(指定键值对的有效期为10s),redis中nis表示空值。
--setrange(改变值中的数据,比如替换邮箱) 格式: setrange eamil 10 163.com [原来已经 set email 254135495@qq.com] 从第10个字符开始替换为163.com
**说明:使用setrange时,如果被替换的字符比新取代的字符要长,那么只会根据新字符的个数替换相应的个数,被替换后面多的追加在新的后面输出-。
--mset 一次性设置多个值 成功ok 失败0..
--mget 批量获取
--msetnx 一次性设置多个值,不会替换原来的值。
--getset 获取旧值,返回新值。格式:getset key value //如果之前不存在这个key则为nil
--getrange 截取value值得一部分长度 getrange key x y [0为下标起始点 从x位开始截,取到第y个]
--incr 自增一个key的value值 即:value++ 格式: incr key
--incrby 与incr类似,加指定值。格式: incrby key 5 //加上5 ====接负数减指定值
--append key abc //给key的value在尾部拼接上abc字符串
--strlen 查看key的value的长度..

——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
2.hash类型:hash是一个string类型的field和value的映射表。它的添加、删除操作都是0/1。hash特别适合用于存储对象。
相对于对象的每个字段存成单个string类型。将一个对象存储在hash类型中会占用更少的内存,并且很方便存取。

方法
--hset 格式:hset myhash field hello 设置hash field为指定值,如果key不存在,则先创建。
--hget: -- 获取设置的值 格式 hget myhash field
--hsetnx 格式:hsetnx myhash field value //与setnx类似 若之前存在该fiel则不进行替换。
--hmset //批量设置 格式: hmset myhash field1 value1 field2 value2
--hmget //批量获取 格式:hmget myhash field1 field2 field3...
--hincrby //与incrby相似,加指定值.格式 hincrby myhash field 5
--hexists //判断哈希表中某个字段是否存在,1/0...
--hlen //返回哈希表field(键)的数量 -hlen myhash
--hdel //删除指定hashfield字段 - hdel myhash name //删除myhash中的name字段
--hkeys //返回哈希表中所有的field (键) 不好用
--hvals //返回哈希表中所有的值 (值) 不好用
--hgetall //同时返回所有的键值 推荐、好用

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
3.list类型:list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等,操作中key理解为链表的名字。redis的list
类型其实就是一个每个子元素都是string类型的双向链表。我们可以通过push、pop操作从链表头部或者尾部添加删除元素,即可以作为栈
,又可以作为队列。

栈:堆栈,底部是密封的(只允许在表的一端进行插入和删除运算,这端称为栈顶)..所以先进后出
队列:相当于管道,通的..所以先进先出
list类型..既可以为栈又可以为队列

php中两个函数:
array_push--- 将元素插入数组末尾(入栈)
array_pop --- 将数组最后一个元素弹出(删除)(出栈)

小技巧:从尾到头为向上 指向头的是前。
方法:
--lpush -- 从头部压入一个元素 格式:lpush mylist1 value1 等于栈的功能 先进后出 [堆栈]
--rpush -- 从尾部压入一个元素 格式:rpush mylist1 value1 等于列队功能 先进先出
--linsert --- 在key对应list的特定位置前或后添加字符串 linsert mylist before value value1 //value为list集合中已存在的值,value1为新增加的值
--lrange //定义取元素的数量 格式:lrange mylist1 0 -1 //解释:**{0 -1} 代表从头的第一个元素,一直取到尾部的最后一个元素。即把数据全部取出来..
--lset --设定list中指定下标的元素值 // lset mylist 0 string //将下标为0的值改成string 最上方的一个值下标即为0,最后一个为-1
--lrem --从key对应的list中删除n个和value1相同的元素。// lrem mylist n value1 (n<0从尾删除,n=0全部删除)
--ltrim --保!留!指定key范围内的数据。。即删除所有不!在!此!范!围!内的数据。 //ltrim mylist 2 -1 //由于redis下标从0开始,故这里会删除前2个元素
--lpop -- 从头弹出(删除)一个元素,并返回该弹出(删除)的元素 //lpop mylist
--rpop -- 从尾弹出(删除)一个元素。。同上
--rpoplpush --从mylist1尾部弹出(删除)一个元素,并且将该元素从mylist2的头部插入 // rpoplpush mylist1 mylist2
--lindex -- 根据index返回元素的值 // lindex mylist 2 //返回索引下标为2的值 -- 记住下标是从0开始计算的
--llen -- 返回mylist元素的个数 //llen mylist

———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

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

#集合中不允许有重复的值,且set集合没有顺序的。取元素只能是随机取。
方法:
--sadd //向myset中添加元素 --sadd myset value1
--srem //删除元素 -- srem myset value
--smembers myset //查看myset中的元素 #########
--spop //由于set类型是一种无序集合,故这里只代表随机弹出(删除)myset中的一个元素 -- spop myset
---------差集
--sdiff //返回两个集合的差集 //谁在前面就以谁为标准.. --sdiff myset1 myset2 //以myset1为标准 返回myset1中有,而myset2中没有的元素。//这就叫做差集
--sdiffstore //返回myset1,myset2两个集合的差集,并将结果赋给myset3 --sdiffstore myset3 myset1 myset2
---------交集
--sinter //返回两个集合的交集 --sinter myset1 myset2
--sinterstore //返回myset1,myset2两个集合的交集,并将结果赋给myset3 --sdiffstore myset3 myset1 myset2
---------并集
--sunion //返回两个集合的并集 --sinter myset1 myset2
--sunionstore //返回myset1,myset2两个集合的并集,并将结果赋给myset3 --sdiffstore myset3 myset1 myset2
--smove //将myset1的值value1移入到myset2中(剪切->粘贴) --smove myset1 myset2 value1
--scard //返回集合中元素个数 -- scard myset1
--sismember //判断某元素是否为集合的元素 -- sismember myset value
--srandmember //随机返回一个元素,但是不删除元素 --srandmember myset

———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
5.sorted sets(zset)有序集合:它是set的一个升级版本,它在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,
每次指定后,zset会自动重新按新的值调整顺序。可以理解为有两列的mysql表,一列存value,一列存顺序。操作中的key理解为zset的名字。
--添加的顺序我们叫序号,与索引是不同的(索引从0开始自增)。


方法:
--zadd //向myzset集合中 添加 元素并且指定序号为1 -- zadd myzset 1 one
--zrem // 根据value删除元素 -- zrem value
--zincrby //根据value的值增加序号的值(这里设置为5),如果value值不存在则新增这个value,且序号为5(本例中设置的5) -- zincrby myzset 5 value
--zrange //按照序号升序排序输出 --zrange myzset 0 -1 withscores //withscores表示输出顺序号
--zrevrange //按照序号降序排序输出 --zrevrange myzset 0 -1 withscores
--zrank //找出value值对应的索引值(索引从0开始) --zrank myzset value
--zrevrank //先按序号降序排序(默认是升序排列好了规则,),然后在找出值的索引。--zrevrank myzset value
--zrangebyscore // 先升序排序,然后根据给定的序号范围,输出在此范围之间的值。zrangebyscore myzset 2 10 withscores //输出序号为2-10的元素的值
--zcount //求出给定序号范围的元素个数 // zcount myzset 2 10 //求出序号2 -10 之间的元素个数
--zcard //集合中所有元素的个数 zcard myzset..
--zremrangebyrank // 先升序排序,然后删除给定的 索!引!范!围!之间的值。-- zremrangebyrank myzset 2 5 //按照索引删除2 - 5的
--zremrangebyscore //同上 按照!序!号!范!围 zremrangebyscore myzset 1 6 //按照序号删掉1-6的


=====================================================================================================================================================
redis常用命名:
键值相关命令:
---keys * //返回所有的键 //keys m* 则取出m打头的键,此处*是模糊匹配,可以放在之前,两边自由组合。
---exists //确认当前库的某个键是否存在
---del //删除一个键
---expire //设置key的过期时间 //ttl 查看该键的剩余过期时间,过期后返回-1
---persist //移除给定key的过期时间
---move //将当前"数据库"的key移入其他的"数据库"; move key1 2 //将当前数据库中的key1移入到2号数据库(剪切--粘贴)
---randomkey 随机返回一个key
---rename //重命名一个key -- rename key new_key
---type //返回键的数据类型 -- type key
---dbsize //返回当前数据库中key的数量
---flushdb //清空当前数据库中的所有key
---flushall //清空所有数据库(0 ~ 15号数据库)中的所有key

服务器相关命令:
---ping //ping的通返回PONG,否则出现错误。
---echo //与php的echo意思一样..
---select //选择一个数据库,redis默认是16个数据库,0-15表示,select 1则选择1数据库,默认是进入的是0数据库。
---quit/exit //退出
---info //服务器相关信息
---config get * //返回相关配置的参数,此处是返回所有。//返回单个如:config get dir

======================================================================================================================================================
高级应用:
一.安全性 --- redis速度快..1s中可以进行15w次密码破解...

设置密码:两种方式
(1)redis.conf -> requirepass 123456 //搜索requirepass 到后面加上你需要的密码就行 越复杂越好~
(2)redis 127.0.0.1:6379 > config set requirepass 123456 //通过命令行
授权 auth 123456 //123456是密码
————————————————————————————————————————————————————————————————————————————————————————
二.主从复制

特点:
主服务器可以拥有多个从服务器。
从服务器与从服务器之间还可以相互连接。(当主服务器宕掉后,从服务器立马变成主机)
主从复制不会阻塞master(主服务器),在同步数据时,master还可以继续处理client的请求
提高系统的伸缩性

配置非常之简单...

(1).在从服务器的配置文件中查找 # slaveof <masterip> <masterport>
改成 slaveof 主服务器ip 主服务器端口

(2).如果主服务器设置了密码 # masterauth <master-password>
改成 masterauth 主服务器的密码

OK... 调用info命名即可以查看主从的信息..
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
三.事务处理(对事务功能的支持比较薄弱..)
(1):说明 -- redis对事务的支持目前还比较简单。redis只能保证一个client发起的事务中的命令可以连续的执行,而中间
不会插入其他client的命令。当一个client在一个连接中发出multi命令时,这个连接会进入一个事物上下文,该
连接后续命令不会立即执行,而是先放到一个队列中,当执行exec命令时,redis会顺序的执行队列中的所有命令。


(2): 实现:

redis 127.0.0.1:6379> .. //一些redis命令
redis 127.0.0.1:6379> multi //开启事务,后续的命令不会立即执行..直到遇见exec
redis 127.0.0.1:6379> set name zhangsan
QUEUED //返回值并不是OK,而是QUEUED代表等待的意思
redis 127.0.0.1:6379> set age 20
QUEUED
redis 127.0.0.1:6379> exec
1)OK
2)OK //此时才执行并返回了2个OK

执行事务 --- exec
取消事务 --- discard

乐观锁... watch
假设数据库中存在一个key age..
窗口1: watch age(监听age) multi(开启事务) <--若是其他窗口已经修改过age,则无法再另外的窗口进行修改提交--> exec(执行)
窗口2://可以对age进行修改... 窗口1则不能再修改..因为此时的版本已经++了

 

——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————



四.持久化机制 -- 内存中的数据同步到硬盘来保证持久性..
两种实现方式:
(1) 快照的方式、默认的。文件名为dump.conf
配置文件中 .. save 900 1 #900S内、如果超过1个key被修改,则发起快照保存!!
save 300 10 #300s内10个key改动.则发起快照保存!!
save 60 10000 #60s内10000key改动.则发起快照保存!!
//规则还可以配置多条
**快照方式是在一定间隔时间做一次的,所以如果redis意外的宕机,也会丢失最后一次的所有修改。

(2) 将操作(增、删、改)存在文件中。aof方式.. 将命名保存在aof文件中..
配置文件中.. 将appendonly no 改成 appendonly yes 则表示启用aof持久化方式.
其中fsync(同步函数)有写入的三种时机配置:
-- 1 # appendfsync always //收到命名就立即写入磁盘,最慢。优点是保证了完全的持久化!!
-- 2 appendfsync everysec //每秒写入一次..相当于一个折中的办法 -- 也是默认开启的配置
-- 3 # appendfsync no //依赖于OS,性能最好,持久化不保证...


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

—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

五.发布订阅消息 .......web聊天系统.......
pub/sub 消息通信模式,主要是解除消息发布者和消息订阅者之间的耦合,redis作为一个pub/sub的server,在订阅者和发布者之间
起到了消息路由的功能。订阅者可以通过 subscribe/psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将信息类型称为
通道(channel),当发布者通过publish命令向redis server发送特定类型的信息时,订阅该信息类型的全部client都会收到此消息。


监听频道 窗口1:subscribe/psubscribe CCTV100 //监听1个频道。
窗口2:subscribe/psubscribe CCTV100 CCTV50 //监听2个频道。

发布消息 publish CCTV100 "content" //像CCTV100这个频道发布一条消息,所有订阅了这个频道的都会收到消息。


——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————


六.虚拟内存使用

这里的虚拟内存与操作系统的虚拟内存并不是一回事,但是思路和目的都是相同的。就是暂时把不!经!常!访!问!的!数!据!从!内!存!交!换!到!磁!盘!中,
从而腾出宝贵的内存空间用于其他需要访问的数据。

really-use-vm yes //确认使用
vm-enabled yes //开启
vm-swap-file /path //路径
vm-max-memory 1000000 //最大内存
vm-page-size 32
vm-pages 134217728
vm-max-threads 4 //线程

... OK