# redis 数据类型、持久化、pyredis 、mongodb
* 数据类型
* 持久化机制
* 安装 Python 扩展 pyredis
* 安装 mongodb
* pymongo
## 数据类型
string\hash\list\set\zset
```
set key value
mset key1 value1 key2 value2
setex key 时间 value
get key
mget key1 key2
incr key
decr key
incrby
decrby
incrbyfloat
append
strlen
exists key
type key
del key
expires key 时间 秒 -1表示 永不过期
ttl key
```
```
hset user name wanghao
hmset users id 1 name wanghao age 18 sex 0
hget key 字段名
hmget key name age sex 获取多个属性的值
hgetall key 获取所有的属性和值
hkeys key 获取所有的属性
hvals key 获取所有的值
hlen key #hash里边有多少个字段 数据的个数
hexists key 字段名 判断属性是否存在
hdel key 字段名 删除 删除属性和值
hstrlen key 字段名
```
> hash 就是 string 键值对的集合 一个hash 可以存放 2的32次方 -1 个键值对
### list 列表类型 比较像js中的 栈方法 和 队列方法
#### 设置
```
lpush key 值 从开头位置插入
rpush key 值 用右侧插入 从尾部插入
127.0.0.1:6379> lpush sql mysql
(integer) 1
127.0.0.1:6379> lpush sql sqlserver
(integer) 2
127.0.0.1:6379> lpush sql oracle
(integer) 3
127.0.0.1:6379> rpush sql redis
(integer) 4
127.0.0.1:6379> rpush sql mongodb
(integer) 5
127.0.0.1:6379> rpush sql memcached
(integer) 6
在指定的元素 redis 前面插入 mongodb
127.0.0.1:6379> linsert sql before redis mongodb
(integer) 3
在指定的元素 mongodb 后面 插入元素sqlserver
127.0.0.1:6379> linsert sql after mongodb sqlserver
(integer) 4
127.0.0.1:6379> lrange sql 0 3
1) "mysql"
2) "mongodb"
3) "sqlserver"
4) "redis"
```
#### 获取
```
lrange key start stop # start 开始位置 stop 结束的位置 包含 开始和结束的位置
127.0.0.1:6379> lrange sql 0 5
1) "oracle"
2) "sqlserver"
3) "mysql"
4) "redis"
5) "mongodb"
6) "memcached"
127.0.0.1:6379> lpop sql 弹出队列 开头第一个值
"oracle"
127.0.0.1:6379> rpop sql 弹出队列 结尾第一个值
"memcached"
lrange sql start stop #start stop称之为 偏移量 偏移量可以为 负数
127.0.0.1:6379> lrange sql 0 3
1) "sqlserver"
2) "mysql"
3) "redis"
4) "mongodb"
127.0.0.1:6379> ltrim sql 1 2 截取下标 1 到下标2 最后留下的就是下标1 和下标2
OK
127.0.0.1:6379> lrange sql 0 3
1) "mysql"
2) "redis"
llen key 查看队列中有多少值
127.0.0.1:6379> llen sql
(integer) 2
lindex key index
127.0.0.1:6379> lindex sql 1 查看索引为1 的值
"redis"
127.0.0.1:6379> lindex sql 0
"mysql"
```
### set 无序集合 元素类型为 string 元素具有唯一性 不重复
#### 设置
```
sadd key value1 value2 value3 # key不要跟已经存在的 重复
```
#### 获取
```
smembers key 获取指定key 集合的所有元素
127.0.0.1:6379> scard sidatianwang #返回元素的个数
(integer) 4
127.0.0.1:6379> sadd sidatianwang liudehua guofucheng liming zhangxueyou
(integer) 4
127.0.0.1:6379> sadd yazhouwuwang guofucheng luozhixiang zhangyixing hangeng zhaosi
求交集
sinter key1 key2
127.0.0.1:6379> SINTER sidatianwang yazhouwuwang
1) "guofucheng"
求差集 谁在前面 以谁为准
127.0.0.1:6379> sdiff sidatianwang yazhouwuwang
1) "liudehua"
2) "zhangxueyou"
3) "liming"
127.0.0.1:6379> sdiff yazhouwuwang sidatianwang
1) "luozhixiang"
2) "zhaosi"
3) "hangeng"
4) "zhangyixing"
求合集
key1 key2
127.0.0.1:6379> sunion sidatianwang yazhouwuwang
1) "zhaosi"
2) "hangeng"
3) "liudehua"
4) "liming"
5) "luozhixiang"
6) "zhangxueyou"
7) "zhangyixing"
8) "guofucheng"
查看元素是否在集合中
127.0.0.1:6379> sismember sidatianwang zhaosi 查看zhaosi 是否在四大天王中
(integer) 0
127.0.0.1:6379> sadd dongbeif4 songxiaobao liuneng zhaosi xiaoshenyang
(integer) 4
127.0.0.1:6379> sadd dongbeif4 liuneng
(integer) 0
```
#### zset 有序集合 元素类型为 string 元素具有唯一性 不重复
#### 设置
```
127.0.0.1:6379> zadd kangbazi 0 zelinx
(integer) 1
127.0.0.1:6379> zadd kangbazi 0 qulinx
(integer) 1
127.0.0.1:6379> zadd kangbazi 1 shimin
(integer) 1
127.0.0.1:6379> zadd kangbazi 1 yuzhao
(integer) 1
127.0.0.1:6379> zadd kangbazi 2 wanyang
(integer) 1
127.0.0.1:6379> zadd kangbazi 3 linzhen
(integer) 1
127.0.0.1:6379> zadd kangbazi 4 wanghao
(integer) 1
做开发的时候 这个 0 1 2 3 4 代表 传过来的 id 可以使用incr 对 id 自增 然后完成排序
#取出集合中的元素
127.0.0.1:6379> zrange kangbazi 0 6
1) "qulinx"
2) "zelinx"
3) "shimin"
4) "yuzhao"
5) "wanyang"
6) "linzhen"
7) "wanghao"
#根据分数取出元素
127.0.0.1:6379> zrangebyscore kangbazi 0 1 取出 0分 和 1分
1) "qulinx"
2) "zelinx"
3) "shimin"
4) "yuzhao"
127.0.0.1:6379> zrangebyscore kangbazi 2 3 2分和 3分的
1) "wanyang"
2) "linzhen"
127.0.0.1:6379> zrangebyscore kangbazi 3 4
1) "linzhen"
2) "wanghao"
value = 传递过来的内容
key = shangpin
flag = 0
num = 100
zadd key incr(flag) value
if flag>100:
return 'over' 秒杀结束
集合中元素的个数
zcard key
127.0.0.1:6379> zcard kangbazi
(integer) 7
统计 分数在 2 到 3之间的元素个数
127.0.0.1:6379> zcount kangbazi 2 3
(integer) 2
#列出元素对应的 分数
127.0.0.1:6379> zscore kangbazi linzhen
"3"
```
## redis 补充
> redis有 16个 库 0~15号库
```
设置 密码
先登录上
redis-cli -h 127.0.0.1 -p 6379
config set requirepass kangbazi
重新登录
auth kangbazi
keys * 列数redis中所有的key
keys n* 列出n开头的key
127.0.0.1:6379> select 1 选择 1号库 select 15 选择 15号库
OK
127.0.0.1:6379[1]>
flushdb 删除当前库中所有的key
flushall 删除所有库中的key
```
## 安装 python redis模块
```
https://github.com/andymccurdy/redis-py
1.pip install redis
2.git clone https://github.com/andymccurdy/redis-py.git
cd redis-py
python setup.py install
>>> import redis
>>> r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi')
>>> r.set('name','python1806')
True
>>> r.get('name')
b'python1806'
b代表字节的意思
默认情况下 设置 或者 获取 的值都是字节类型
如果想要 str类型 需要 再加一个参数
>>>r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi',decode_responses=True)
>>> r.get('name')
'python1806' #这样就没有 字母 b了
```
### Python 操作redis
```python
strings.py
import redis
r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi',decode_responses=True)
#r.set('names','kangbazi')
#r.setex('haha',30,'kangbazihaha')
#r.mset(name1='mysql',name2='redis',name3='mongodb')
#r.mset({"name1":'mysql',"name2":'redis',"name3":'mongodb'})
r.set('num',10)
```
```python
getstrings.py
import redis
r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi',decode_responses=True)
#print(r.get('haha'))
#print(r.mget('name1','name2','name3'))
#print(r.strlen('haha'))
#print(r.incr('num'))
#print(r.decr('num'))
#print(r.incr('num',amount=100))
#print(r.incrbyfloat('num',amount=12.34))
r.append('num','mayun')
print(r.get('num'))
```
### hash
```python
import redis
r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi',decode_responses=True)
#r.hset('user','name','zelinx')
data={"name":"qulinx","age":18,"sex":0,"height":"181cm"}
r.hmset('user',data)
```
```python
import redis
r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi',decode_responses=True)
#print(r.hget('user','name'))
#print(r.hgetall("user"))
print(r.hmget('user','name','age',"sex"))
```
### list
```python
import redis
r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi',decode_responses=True)
r.lpush('quene','zelinx')
r.rpush('quene','qulinx','shimin','yuzhjao')
```
```python
import redis
r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi',decode_responses=True)
print(r.lrange('quene',0,-1)) #表示取出所有
print(r.lindex('quene',3))
```
### set
```
import redis
r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi',decode_responses=True)
r.sadd("setname","python1806")
r.sadd("setname","python1806","python1807","python1808")
```
```
import redis
r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi',decode_responses=True)
print(r.smembers('setname'))
```
### zset
```
import redis
r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi',decode_responses=True)
r.zadd("person","wanyang",1,"wanghao",2,"linzhen",3)
r.zadd("person",wanyang=1,wanghao=2,linzhen=3)
```
```
import redis
r=redis.StrictRedis(host='localhost',port=6379,db=0,password='kangbazi',decode_responses=True)
print(r.zrange('person',开始分数,结束分数,desc=true))
print(r.zscore('person',"wanyang")) # 1
```
### 删除 键
```
r.delete(key)
```
### 判断键是否存在
```
r.exists(key)
```
### 设置过期时间
```
r.expire(key,time)
```
### 查看类型
```
type(key)
```
### key重命名
```
r.rename("原名字","新名字")
```
## mongodb
> https://www.mongodb.com/download-center?jmp=nav#community
## redis 持久化机制
* rdb redis database
* aof append of file
### rdb
```
在指定的时间间隔内 将内存这种的数据 以快照的形式写入到磁盘中
首先 /usr/local/redis 下面 src目录下面 redis-server 会创建子进程 子进程 会在指定的时间间隔内 将数据写入到 /usr/local/redis/src/ 下面的 dump.rdb 中 第一次它写入的是一个 临时的dump.rdb 当写完以后 临时的dump.rdb 会替换到 原来的 dump.rdb
/usr/local/redis/redis.conf 第39行
指定存放redis数据的文件名称及路径
指定的间隔 :
202-204 行
save 900 1 900秒内 1个key 发生了改变 那么 发起快照保存
save 300 10 300秒内 10个key 发生改变 发起快照保存
save 60 10000 60秒内 10000 key 发生改变 发起快照保存
手动发起rdb备份
redis-cli -h 127.0.0.1 -p 6379 -a kangbazi save
redis-cli -h 127.0.0.1 -p 6379 -a kangbazi bgsave
bgsave 后台备份的意思 也会单独开设一个进程 进行操作
```
### aof
```
以日志的形式 记录 每一个对redis的增删改操作 当服务器重启的时候 重新执行这些命令 然后将数据恢复到内存中
redis-cli ->发送命令 给 redis-server -> 同时将命令 写入到 appendonly.aof
默认 aof 没有开启
开启 aof
appendonly no #将no改为 yes
appendfilename "appendonly.aof"
记得重启 redis
# appendfsync always 只要有新命令就执行一次 安全性高 效率慢
appendfsync everysec 每秒同步一次 兼顾效率和安全性
# appendfsync no 从不同步 效率快 但是安全性低
```
### 安装 mongodb
```
wget -c https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-4.0.2.tgz
tar -zxvf mongodb-linux-x86_64-ubuntu1604-4.0.2.tgz
sudo mv mongodb-linux-x86_64-ubuntu1604-4.0.2 /usr/local/mongodb
创建一个目录 用来存放 mongodb 数据库文件
bai@bai-virtual-machine:~$ sudo mkdir -p /data/db
cd /usr/local/mongodb/bin
export PATH=/usr/local/mongodb/bin:$PATH
sudo ./mongod --dbpath=/data/db --logpath=/usr/local/mongodb/mongodb.log --logappend & #启动
#连接
任何 目录 都可以
mongo 直接可以连接
use 数据库名称 创建 并且切换到该数据库
show dbs 列出所有的数据库 这时候有并没有刚才创建的
db.新创建的数据库.insert({"name":"kangbazi","age":18})
show dbs 里边就会有新创建的数据库了
> use qfedu
switched to db qfedu
> db.dropDatabase()
{ "dropped" : "qfedu", "ok" : 1 }
help 查看帮助文件
exit 退出连接
```
## 安装 pymongo
```
1.git clone https://github.com/mongodb/mongo-python-driver.git
cd mongo-python-driver
python setup.py install
2.pip install pymongo
python
import pymongo 如果不报错 说明执行成功
```