Redis 数据类型python
-- String 字符串git
-- redis的string能够包含任何数据,包括图片以及序列化的对象,一个键最大能存储512MB。github
-- Hash 哈希redis
-- redis的hash是一个String类型的key和value的映射表,hash特别适合存储对象,类比python字典。数据库
-- List 列表windows
-- redis的list是简单的字符串列表,按照插入顺序排序,能够从两端进行添加,相似于双向链表,列表还能够进行阻塞。缓存
-- Set 集合服务器
-- redis的set是字符串类型的无序且不重复集合。集合是经过哈希表实现的,因此添加,删除,查找的时间复杂度都是O(1)。app
-- Zset 有序集合tcp
-- redis的zset和set同样,不一样的是每一个元素都会关联一个double类型的分数,redis正是经过对分数的排序对集合进行有序存储。
Redis 支持 32 位和 64 位。这个须要根据你系统平台的实际状况选择,这里咱们下载 Redis-x64-xxx.zip压缩包到 C 盘,解压后,将文件夹从新命名为 redis
若是下载过慢的话,能够下载国内的资源:http://download.csdn.net/detail/shzy1988/9716082
打开一个 cmd 窗口 使用cd命令切换目录到 C:\redis 运行
redis-server.exe redis.windows.conf
若是想方便的话,能够把 redis 的路径加到系统的环境变量里,这样就免得再输路径了,后面的那个 redis.windows.conf 能够省略,若是省略,会启用默认的。输入以后,会显示以下界面
这时候另启一个cmd窗口,原来的不要关闭,否则就没法访问服务端了。
切换到redis目录下运行 redis-cli.exe -h 127.0.0.1 -p 6379 。
设置键值对 set myKey abc
取出键值对 get myKey
在Python中安装redis模块
pip3 install redis
在Python中使用redis
import redis # 导入redis模块,经过python操做redis 也能够直接在redis主机的服务端操做缓存数据库 r = redis.Redis(host='localhost', port=6379, decode_responses=True) # host是redis主机,须要redis服务端和客户端都启动 redis默认端口是6379, decode_responses=True 表示存储的数据为字符串类型,默认为bytes类型 r.set('name', 'junxi') # key是"foo" value是"bar" 将键值对存入redis缓存 print(r['name']) print(r.get('name')) # 取出键name对应的值 print(type(r.get('name')))
当程序建立数据源实例是,系统会一次性建立多个数据库链接,并把这些数据库链接保存在链接池中,当程序须要进行对数据库访问时,无需从新新建数据库链接,而是从链接池中取出一个空闲的数据库链接
import redis # 导入redis模块,经过python操做redis 也能够直接在redis主机的服务端操做缓存数据库 pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) # host是redis主机,须要redis服务端和客户端都起着 redis默认端口是6379 r = redis.Redis(connection_pool=pool) r.set('gender', 'male') # key是"gender" value是"male" 将键值对存入redis缓存 print(r.get('gender')) # gender 取出键male对应的值
set(name, value, ex=None, px=None, nx=False, xx=False)
在Redis中设置值,默认,不存在则建立,存在即修改
参数
实例演示:
ex,过时时间(秒) 这里过时时间是3秒,3秒后p,键food的值就变成None
import redis pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.set('food', 'mutton', ex=3) # key是"food" value是"mutton" 将键值对存入redis缓存, ex=3表示3秒后food对应的value为none, print(r.get('food')) # mutton 取出键food对应的值
nx,若是设置为True,则只有name不存在时,当前set操做才执行 (新建)
import redis pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) print(r.set('fruit', 'watermelon', nx=True)) # True--不存在 # 若是键fruit不存在,那么输出是True;若是键fruit已经存在,输出是None
setnx(name, value)
设置值,只有name不存在时,执行设置操做(添加)
print(r.setnx('fruit1', 'banana')) # fruit1不存在,输出为True
setex(name, value, time)
参数: time ,过时时间,(数字秒或timedelalta对像
import redis import time pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.setex("fruit2", "orange", 5) print(r.get('fruit2')) # 5秒后,取值就从orange变成None
psetex(name, time_ms, value)
参数: time_ms,过时时间(数字毫秒或 timedelta对象
r.psetex("fruit3", 5000, "apple") time.sleep(5) print(r.get('fruit3')) # 5000毫秒后,取值就从apple变成None
批量设置值
r.mget({'k1': 'v1', 'k2': 'v2'}) r.mset(k1="v1", k2="v2") # 这里k1 和k2 不能带引号 一次设置对个键值对 print(r.mget("k1", "k2")) # 一次取出多个键对应的值 print(r.mget("k1"))
批量取值
print(r.mget('k1', 'k2')) print(r.mget(['k1', 'k2'])) print(r.mget("fruit", "fruit1", "fruit2", "k1", "k2")) # 将目前redis缓存中的键对应的值批量取出来
getset(name, value)
设置新值,并取出原来的值
print(r.getset("food", "barbecue")) # 设置的新值是barbecue 设置前的值是beef
getrange(key, start, end)
获取子序列(根据字节获取,非字符)
参数:
name, redis的key
start: 启始位置(字节)
end:结束位置(字节)
如: "骑士" , 0-3表示 骑
r.set("cn_name", "东方月初") # 汉字 print(r.getrange("cn_name", 0, 2).decode('utf8')) # 取索引号是0-2 前3位的字节 东 切片操做 (一个汉字3个字节 1个字母一个字节 每一个字节8bit) print(r.getrange("cn_name", 0, -1)) # 取全部的字节 东方月初 切片操做 r.set("en_name","junxi") # 字母 print(r.getrange("en_name", 0, 2)) # 取索引号是0-2 前3位的字节 jun 切片操做 (一个汉字3个字节 1个字母一个字节 每一个字节8bit) print(r.getrange("en_name", 0, -1)) # 取全部的字节 junxi 切片操做
setrange(name, offset, value) (没看懂)
修改字符串内容,从指定字符安串索引开始向后替换(若是新值比原值长,没法添加)
参数:
offset 字符串的索引,字节(一个汉字三个字节,索引是从0开始的)
value 值只是是1 或 0
注:若是在Redis中有一个对应: n1 = "foo", 那么字符串foo的二进制表示为:01100110 01101111 01101111 因此,若是执行 setbit('n1', 7, 1),则就会将第7位设置为1, 那么最终二进制则变成 01100111 01101111 01101111,即:"goo" 扩展,转换二进制表示: source = "陈思惟" source = "foo" for i in source: num = ord(i) # ord方法返回单字符字符串的Unicode编码点 print bin(num).replace('b','') 特别的,若是source是汉字 "陈思惟"怎么办? 答:对于utf-8,每个汉字占 3 个字节,那么 "陈思惟" 则有 9个字节 对于汉字,for循环时候会按照 字节 迭代,那么在迭代时,将每个字节转换 十进制数,而后再将十进制数转换成二进制 11100110 10101101 10100110 11100110 10110010 10011011 11101001 10111101 10010000
gitbit(name, offset)
获取name对应的值的二进制表示中的某位值(0 或者1)
print(r.getbit("foo1", 0)) # 0 foo1 对应的二进制 4个字节 32位 第0位是0仍是1
bitcount(key, start=None, end=None) 了解
获取name对应的二进制表示中1的个数
参数
key redis的name
start 字节启始位置
end 字节结束位置
print(r.get("foo")) # goo1 01100111 print(r.bitcount("foo",0,1)) # 11 表示前2个字节中,1出现的个数
hset(name, key, value) 增长单个 不存在则建立 hget(name, key) 获取单个 hmset(name, mapping) 批量增长 mapping为字典 hgetall(name) 获取name对应hash的全部键值 hlen(name) 获取name对应的hash中键值对的个数 hkeys(name) 获取name对应的hash中全部的key的值 hvals(name) 获取name对应的hash中全部的value的值 hexists(name, key) 检查name对应的hash是否存在当前传入的key hdel(name,*keys) 将name对应的hash中指定key的键值对删除 hscan_iter(name, match=None, count=None) 利用yield封装hscan建立生成器,实现分批去redis中获取数据 参数: match,匹配指定key,默认None 表示全部的key count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数
单个增长--修改(单个取出)--没有就新增,有的话就修改
hset(name, key, value)
name对应的hash中设置一个键值对(不存在,则建立;不然,修改)
参数:
name,redis的name
key,name对应的hash中的key
value,name对应的hash中的value
注:
hsetnx(name, key, value),当name对应的hash中不存在当前key时则建立(至关于添加)
import redis import time pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.hset("hash1", "k1", "v1") r.hset("hash1", "k2", "v2") print(r.hkeys("hash1")) # 取hash中全部的key print(r.hget("hash1", "k1")) # 单个取hash的key对应的值 print(r.hmget("hash1", "k1", "k2")) # 多个取hash的key对应的值 r.hsetnx("hash1", "k2", "v3") # 只能新建 print(r.hget("hash1", "k2"))
lpush(name,values) 在name对应的list中左边添加元素 没有就新建 llen(name) 获取name对应的列表长度 lrang(name, index1, index2) 按照index切片取出name对应列表里值 lpushx(name, value) 只能添加不能新建 linsert(name, where, refvalue, value)) 在name对应的列表的某一个值前或后插入一个新值 参数: name,redis的name where,BEFORE或AFTER refvalue,标杆值,即:在它先后插入数据 value,要插入的数据 lset(name, index, value) 给指定索引修改值 lrem(name, value, num) 在name对应的list中删除指定的值 参数: name,redis的name value,要删除的值 num, num=0,删除列表中全部的指定值; num=2,从前到后,删除2个; num=1,从前到后,删除左边第1个 num=-2,从后向前,删除2个 lindex(name, index) 在name对应的列表中根据索引获取列表元素
import redis r = redis.Redis(host="127.0.0.1", password="", decode_responses=True) r.publish("name", "dongfangyuechu")
import redis r = redis.Redis(host="127.0.0.1", password="", decode_responses=True) # 第一步 生成一个订阅者对象 pubsub = r.pubsub() # 第二步 订阅一个消息 实际上就是监听这个键 pubsub.subscribe("name") # 第三步 死循环一直等待监听结果 while True: print("working~~~") msg = pubsub.parse_response() print(msg)
redis 默认在执行每次请求都会建立(链接池申请链接)和断开(归还链接池) 一次链接操做
若是想要在一次请求中指定多个命令,则可使用管道(pipline)实现一次请求指定多个命令,而且默认状况下一次piplilne是原子性操做
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增长任何维持原子性的机制,因此 Redis 事务的执行并非原子性的。
事务能够理解为一个打包的批量执行脚本,但批量指令并不是原子化的操做,中间某条指令的失败不会致使前面已作指令的回滚,也不会形成后续的指令不作
管道:是redis在提供单个请求中缓冲多条服务器命令基类的子类,它经过减小服务器-客户端之间反复的tcp数据库包,从而大大提升了执行批量命令的功能
import redis import time pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) # pipe = r.pipeline(transaction=False) # 默认的状况下,管道里执行的命令能够保证执行的原子性,执行pipe = r.pipeline(transaction=False)能够禁用这一特性。 # pipe = r.pipeline(transaction=True) pipe = r.pipeline() # 建立一个管道 pipe.set('name', 'jack') pipe.set('role', 'sb') pipe.sadd('faz', 'baz') # 新增 pipe.incr('num') # 若是num不存在则vaule为1,若是存在,则value自增1 pipe.execute() print(r.get("name")) print(r.get("role")) print(r.get("num"))
管道的命令能够写在一块儿
pipe.set('hello', 'redis').sadd('faz', 'baz').incr('num').execute() print(r.get("name")) print(r.get("role")) print(r.get("num"))