1、redis連接
redis-py提供兩個類Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,
並使用官方的語法和命令,Redis是StrictRedis的子類,用於向后兼容舊版本的redis-py。
import redis 導入redis模塊,通過python操作redis 也可以直接在redis主機的服務端操作緩存數據庫
r = redis.Redis(host='192.168.19.130', port=6379) host是redis主機,需要redis服務端和客戶端都起着 redis默認端口是6379
r.set('foo', 'Bar') key是"foo" value是"bar" 將鍵值對存入redis緩存
print r.get('foo') Bar 取出鍵foo對應的值
2、連接池
redis-py使用connection pool來管理對一個redis server的所有連接,避免每次建立、釋放連接的開銷。
默認,每個Redis實例都會維護一個自己的連接池。
可以直接建立一個連接池,然后作為參數Redis,這樣就可以實現多個Redis實例共享一個連接池
import redis 通過python操作redis緩存
pool = redis.ConnectionPool(host='192.168.19.130', port=6379) host是redis主機,需要redis服務端和客戶端都起着 redis默認端口是6379
r = redis.Redis(connection_pool=pool)
r.set('foo', 'Bar') key是"foo" value是"bar" 將鍵值對存入redis緩存
print r.get('foo') Bar 取出鍵foo對應的值
3、redis基本命令_string
set(name, value, ex=None, px=None, nx=False, xx=False)
在Redis中設置值,默認,不存在則創建,存在則修改
參數:
ex,過期時間(秒)
px,過期時間(毫秒)
nx,如果設置為True,則只有name不存在時,當前set操作才執行
xx,如果設置為True,則只有name存在時,當前set操作才執行
import redis 導入redis模塊,通過python操作redis 也可以直接在redis主機的服務端操作緩存數據庫
pool = redis.ConnectionPool(host='192.168.19.130', port=6379)
host是redis主機,需要redis服務端和客戶端都起着 redis默認端口是6379
r = redis.Redis(connection_pool=pool) 創建實例
1 ex,過期時間(秒) 這里過期時間是3秒,3秒后p,鍵foo的值就變成None
r.set('foo', 'Bar',ex=3) key是"foo" value是"bar" 將鍵值對存入redis緩存
print r.get('foo') Bar 取出鍵foo對應的值
2 px,過期時間(豪秒) 這里過期時間是3豪秒,3毫秒后,鍵foo的值就變成None
r.set('foo', 'Bar',px=3) key是"foo" value是"bar" 將鍵值對存入redis緩存
print r.get('foo') Bar 取出鍵foo對應的值
3 nx,如果設置為True,則只有name不存在時,當前set操作才執行 (新建)
print(r.set('foo', 'Bar',nx=True)) None--已經存在
如果鍵foo已經存在,那么輸出是True;如果鍵foo不存在,輸出是None
4 xx,如果設置為True,則只有name存在時,當前set操作才執行 (修改)
print(r.set('foo1', 'Bar',xx=True)) True--已經存在
如果鍵foo已經存在,那么輸出是None;如果鍵foo不存在,輸出是True
5 setnx(name, value)
設置值,只有name不存在時,執行設置操作(添加)
print(r.setnx("foo2","bar")) False--已經存在的話,無法執行
6 setex(name, value, time)
設置值
參數:
time,過期時間(數字秒 或 timedelta對象)
r.setex("foo","bar",5)
print r.get('foo') 5秒后,取值就從bar變成None
7 psetex(name, time_ms, value)
設置值
參數:
time_ms,過期時間(數字毫秒 或 timedelta對象)
r.psetex("foo",5000,"bar")
print r.get('foo') 5000毫秒后,取值就從bar變成None
8 mset(*args, **kwargs)
批量設置值
如:
mset(k1='v1', k2='v2')
或
mget({'k1': 'v1', 'k2': 'v2'})
r.mset(k1="v1",k2="v2") 這里k1 和k2 不能帶引號 一次設置對個鍵值對
print r.mget("k1","k2") ['v1', 'v2'] 一次取出多個鍵對應的值
print r.mget("k1") ['v1']
9 mget(keys, *args)
批量獲取
如:
mget('ylr', 'wupeiqi')
或
r.mget(['ylr', 'wupeiqi'])
print r.mget("foo","foo1","foo2","k1","k2") [None, 'Bar', 'bar', 'v1', 'v2']
將目前redis緩存中的鍵對應的值批量取出來
10 getset(name, value)
設置新值並獲取原來的值
print(r.getset("foo1","bar_NEW")) Bar
設置的新值是"bar_NEW" 設置前的值是Bar
11 getrange(key, start, end)
獲取子序列(根據字節獲取,非字符)
參數:
name,Redis 的 name
start,起始位置(字節)
end,結束位置(字節)
如: "武沛齊" ,0-3表示 "武"
r.set("foo1","武沛齊") 漢字
print(r.getrange("foo1",0,2)) 取索引號是0-2 前3位的字節 武 切片操作 (一個漢字3個字節 1個字母一個字節 每個字節8bit)
print(r.getrange("foo1",0,-1)) 取所有的字節 武沛齊 切片操作
r.set("foo1","bar_new") 字母
print(r.getrange("foo1",0,2)) 取索引號是0-2 前3位的字節 bar 切片操作 (一個漢字3個字節 1個字母一個字節 每個字節8bit)
print(r.getrange("foo1",0,-1)) 取所有的字節 bar_new 切片操作
12 setrange(name, offset, value)
修改字符串內容,從指定字符串索引開始向后替換(新值太長時,則向后添加)
參數:
offset,字符串的索引,字節(一個漢字三個字節)
value,要設置的值
r.setrange("foo1",1,"aaa")
print(r.get("foo1")) baaanew 原始值是bar_new 從索引號是1開始替換成aaa 變成 baaanew
bar_new
13 setbit(name, offset, value)
對name對應值的二進制表示的位進行操作
參數:
name,redis的name
offset,位的索引(將值變換成二進制后再進行索引)
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)
print bin(num).replace('b','')
特別的,如果source是漢字 "陳思維"怎么辦?
答:對於utf-8,每一個漢字占 3 個字節,那么 "陳思維" 則有 9個字節
對於漢字,for循環時候會按照 字節 迭代,那么在迭代時,將每一個字節轉換 十進制數,然后再將十進制數轉換成二進制
11100110 10101101 10100110 11100110 10110010 10011011 11101001 10111101 10010000
-------------------------- ----------------------------- -----------------------------
陳思維
13 應用場景 :統計uv
注:如果在Redis中有一個對應: n1 = "foo",
那么字符串foo的二進制表示為:01100110 01101111 01101111
所以,如果執行 setbit('n1', 7, 1),則就會將第7位設置為1,
那么最終二進制則變成 01100111 01101111 01101111,即:"goo"
r.set("foo","foo1") foo1的二進制表示為:01100110 01101111 01101111 00110001
這里f對應的ascii值是102 折算二進制是 01100110 (64+32+4+2)
這里o對應的ascii值是111 折算二進制是 01101111 (64+32+8+4+2+1)
這里數字1對應的ascii值是49 折算二進制是 00110001 (32+16+1)
r.setbit("foo",7,1) 將第7位設置為1,
print(r.get("foo")) goo1
那么最終二進制則變成 01100111 01101111 01101111 00000001
print(ord("f")) 102 將字符f的ascii對應的值打印出來
print(ord("o")) 111 將字符o的ascii對應的值打印出來
print(chr(103)) g 將ascii數字103對應的字符打印出來
print(ord("1")) 49 將數字1的ascii對應的值打印出來
擴展,轉換二進制表示:
source = "陳思維"
source = "foo1"
for i in source:
num = ord(i)
print(num) 打印每個字母字符或者漢字字符對應的ascii碼值 f-102-0b100111-01100111
print(bin(num)) 打印每個10進制ascii碼值轉換成二進制的值 0b1100110(0b表示二進制)
print bin(num).replace('b','') 將二進制0b1100110替換成01100110
特別的,如果source是漢字 "陳思維"怎么辦?
答:對於utf-8,每一個漢字占 3 個字節,那么 "陳思維" 則有 9個字節
對於漢字,for循環時候會按照 字節 迭代,那么在迭代時,將每一個字節轉換 十進制數,然后再將十進制數轉換成二進制
11100110 10101101 10100110 11100110 10110010 10011011 11101001 10111101 10010000
14 getbit(name, offset)
獲取name對應的值的二進制表示中的某位的值 (0或1)
print(r.getbit("foo1",0)) 0 foo1對應的二進制 4個字節 32位 第0位是0還是1
15 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出現的個數
16 bitop(operation, dest, *keys)
獲取多個值,並將值做位運算,將最后的結果保存至新的name對應的值
參數:
operation,AND(並) 、 OR(或) 、 NOT(非) 、 XOR(異或)
dest, 新的Redis的name
*keys,要查找的Redis的name
如:
bitop("AND", 'new_name', 'n1', 'n2', 'n3')
獲取Redis中n1,n2,n3對應的值,然后講所有的值做位運算(求並集),然后將結果保存 new_name 對應的值中
r.set("foo","1") 0110001
r.set("foo1","2") 0110010
print(r.mget("foo","foo1")) ['goo1', 'baaanew']
print(r.bitop("AND","new","foo","foo1")) "new" 0 0110000
print(r.mget("foo","foo1","new"))
source = "12"
for i in source:
num = ord(i)
print(num) 打印每個字母字符或者漢字字符對應的ascii碼值 f-102-0b100111-01100111
print(bin(num)) 打印每個10進制ascii碼值轉換成二進制的值 0b1100110(0b表示二進制)
print bin(num).replace('b','') 將二進制0b1100110替換成01100110
17 strlen(name)
返回name對應值的字節長度(一個漢字3個字節)
print(r.strlen("foo")) 4 'goo1'的長度是4
18 incr(self, name, amount=1)
自增 name對應的值,當name不存在時,則創建name=amount,否則,則自增。
參數:
name,Redis的name
amount,自增數(必須是整數)
注:同incrby
r.set("foo",123)
print r.mget("foo","foo1","foo2","k1","k2") ['123', '2', 'bar', 'v1', 'v2']
r.incr("foo",amount=1)
print r.mget("foo","foo1","foo2","k1","k2") ['124', '2', 'bar', 'v1', 'v2']
19 incrbyfloat(self, name, amount=1.0)
自增 name對應的值,當name不存在時,則創建name=amount,否則,則自增。
參數:
name,Redis的name
amount,自增數(浮點型)
r.set("foo1","123.0")
print r.mget("foo","foo1","foo2","k1","k2") ['124', '123.0', 'bar', 'v1', 'v2']
r.incrbyfloat("foo1",amount=2.0)
r.incrbyfloat("foo3",amount=3.0)
print r.mget("foo","foo1","foo2","foo3","k1","k2") ['124', '125', 'bar', '-3', 'v1', 'v2']
20 decr(self, name, amount=1)
自減 name對應的值,當name不存在時,則創建name=amount,否則,則自減。
參數:
name,Redis的name
amount,自減數(整數)
r.decr("foo4",amount=3) 遞減3
r.decr("foo1",amount=1) 遞減1
print r.mget("foo","foo1","foo2","foo3","foo4","k1","k2")
['goo1', '121', 'bar', '15', '-18', 'v1', 'v2']
21 append(key, value)
在redis name對應的值后面追加內容
參數:
key, redis的name
value, 要追加的字符串
r.append("foo","abc") 在foo對應的值goo1后面追加字符串abc
print r.mget("foo","foo1","foo2","foo3","foo4","k1","k2")
['goo1abc', '121', 'bar', '15', '-18', 'v1', 'v2']
4 redis基本命令_hash
import redis 導入redis模塊,通過python操作redis 也可以直接在redis主機的服務端操作緩存數據庫
pool = redis.ConnectionPool(host='192.168.19.130', port=6379)
host是redis主機,需要redis服務端和客戶端都起着 redis默認端口是6379
r = redis.Redis(connection_pool=pool) 創建實例
1 單個增加--修改(單個取出)--沒有就新增,有的話就修改
hset(name, key, value)
name對應的hash中設置一個鍵值對(不存在,則創建;否則,修改)
參數:
name,redis的name
key,name對應的hash中的key
value,name對應的hash中的value
注:
hsetnx(name, key, value),當name對應的hash中不存在當前key時則創建(相當於添加)
r.hset("foo_hash1","k1","v1")
print(r.mget("foo","foo1","foo2","foo3","foo4","k1","k2"))
['goo1abcabc', '121', 'bar', '15', '-18', 'v1', 'v2'] 取字符串
print(r.hget("foo_hash1","k1")) v1 單個取hash的key
print(r.hmget("foo_hash1","k1")) ['v1'] 批量取hash的key
r.hsetnx("foo_hash1","k2","v2") 只能新建
print(r.hget("foo_hash1","k2")) v2
print(r.hmget("foo_hash1","k2")) ['v2']
2 批量增加(取出)
hmset(name, mapping)
在name對應的hash中批量設置鍵值對
參數:
name,redis的name
mapping,字典,如:{'k1':'v1', 'k2': 'v2'}
如:
r.hmset('xx', {'k1':'v1', 'k2': 'v2'})
r.hmset("foo_hash2",{"k2":"v2","k3":"v3"})
print(r.hget("foo_hash2","k2")) v2
單個取出"foo_hash2"的key-k2對應的value
print(r.hmget("foo_hash2","k2","k3")) ['v2', 'v3']
批量取出"foo_hash2"的key-k2 k3對應的value --方式1
print(r.hmget("foo_hash2",["k2","k3"])) ['v2', 'v3']
批量取出"foo_hash2"的key-k2 k3對應的value --方式2
hget(name,key)
在name對應的hash中獲取根據key獲取value
hmget(name, keys, *args)
在name對應的hash中獲取多個key的值
參數:
name,reids對應的name
keys,要獲取key集合,如:['k1', 'k2', 'k3']
*args,要獲取的key,如:k1,k2,k3
如:
r.hmget('xx', ['k1', 'k2'])
或
print r.hmget('xx', 'k1', 'k2')
3 取出所有的鍵值對
hgetall(name)
獲取name對應hash的所有鍵值
print(r.hgetall("foo_hash1"))
{'k2': 'v2', 'k1': 'v1'}
4 得到所有鍵值對的格式 hash長度
hlen(name)
獲取name對應的hash中鍵值對的個數
print(r.hlen("foo_hash1")) 2
5 得到所有的keys(類似字典的取所有keys)
hkeys(name)
獲取name對應的hash中所有的key的值
print(r.hkeys("foo_hash1")) ['k1', 'k2'] 取出所有的keys
6 得到所有的value(類似字典的取所有value)
hvals(name)
獲取name對應的hash中所有的value的值
print(r.hvals("foo_hash1")) ['v1', 'v2'] 取出所有的values
7 判斷成員是否存在(類似字典的in)
hexists(name, key)
檢查name對應的hash是否存在當前傳入的key
print(r.hexists("foo_hash1","k3")) False 不存在
print(r.hexists("foo_hash1","k1")) True 存在
8 刪除鍵值對
hdel(name,*keys)
將name對應的hash中指定key的鍵值對刪除
print(r.hgetall("foo_hash1")) {'k2': 'v2', 'k1': 'v1'}
r.hset("foo_hash1","k2","v3") 修改已有的key k2
r.hset("foo_hash1","k1","v1") 新增鍵值對 k1
r.hdel("foo_hash1","k1") 刪除一個鍵值對
print(r.hgetall("foo_hash1")) {'k2': 'v3'}
9 自增自減整數(將key對應的value--整數 自增1或者2,或者別的整數 負數就是自減)
hincrby(name, key, amount=1)
自增name對應的hash中的指定key的值,不存在則創建key=amount
參數:
name,redis中的name
key, hash對應的key
amount,自增數(整數)
r.hset("foo_hash1","k3",123)
r.hincrby("foo_hash1","k3",amount=-1)
print(r.hgetall("foo_hash1")) {'k3': '122', 'k2': 'v3', 'k1': 'v1'}
r.hincrby("foo_hash1","k4",amount=1) 不存在的話,value默認就是1
print(r.hgetall("foo_hash1")) {'k3': '122', 'k2': 'v3', 'k1': 'v1', 'k4': '4'}
10 自增自減浮點數(將key對應的value--浮點數 自增1.0或者2.0,或者別的浮點數 負數就是自減)
hincrbyfloat(name, key, amount=1.0)
自增name對應的hash中的指定key的值,不存在則創建key=amount
參數:
name,redis中的name
key, hash對應的key
amount,自增數(浮點數)
自增name對應的hash中的指定key的值,不存在則創建key=amount
r.hset("foo_hash1","k5","1.0")
r.hincrbyfloat("foo_hash1","k5",amount=-1.0) 已經存在,遞減-1.0
print(r.hgetall("foo_hash1"))
r.hincrbyfloat("foo_hash1","k6",amount=-1.0) 不存在,value初始值是-1.0 每次遞減1.0
print(r.hgetall("foo_hash1")) {'k3': '122', 'k2': 'v3', 'k1': 'v1', 'k6': '-6', 'k5': '0', 'k4': '4'}
11 取值查看--分片讀取
hscan(name, cursor=0, match=None, count=None)
增量式迭代獲取,對於數據大的數據非常有用,hscan可以實現分片的獲取數據,並非一次性將數據全部獲取完,從而放置內存被撐爆
參數:
name,redis的name
cursor,游標(基於游標分批取獲取數據)
match,匹配指定key,默認None 表示所有的key
count,每次分片最少獲取個數,默認None表示采用Redis的默認分片個數
如:
第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None)
第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None)
...
直到返回值cursor的值為0時,表示數據已經通過分片獲取完畢
print(r.hscan("foo_hash1"))
(0L, {'k3': '122', 'k2': 'v3', 'k1': 'v1', 'k6': '-6', 'k5': '0', 'k4': '4'})
12 hscan_iter(name, match=None, count=None)
利用yield封裝hscan創建生成器,實現分批去redis中獲取數據
參數:
match,匹配指定key,默認None 表示所有的key
count,每次分片最少獲取個數,默認None表示采用Redis的默認分片個數
如:
for item in r.hscan_iter('xx'):
print item
print(r.hscan_iter("foo_hash1")) <generator object hscan_iter at 0x027B2C88> 生成器內存地址
for item in r.hscan_iter('foo_hash1'):
print item
('k3', '122')
('k2', 'v3')
('k1', 'v1')
('k6', '-6')
('k5', '0')
('k4', '4')
5 redis基本命令_list
import redis 導入redis模塊,通過python操作redis 也可以直接在redis主機的服務端操作緩存數據庫
pool = redis.ConnectionPool(host='192.168.19.130', port=6379)
host是redis主機,需要redis服務端和客戶端都起着 redis默認端口是6379
r = redis.Redis(connection_pool=pool) 創建實例
1 增加(類似於list的append,只是這里是從左邊新增加)--沒有就新建
lpush(name,values)
在name對應的list中添加元素,每個新的元素都添加到列表的最左邊
如:
r.lpush('oo', 11,22,33)
保存順序為: 33,22,11
擴展:
rpush(name, values) 表示從右向左操作
r.lpush("foo_list1",11,22) 從列表的左邊,先添加11,后添加22
print(r.lrange("foo_list1",0,20))
['22', '11', '22', '11', '22', '11', '22', '11', '22', '11', '22', '11', '22', '11', '22', '11', '22', '11']
切片取出值,范圍是索引號0-20
print(r.llen("foo_list1")) 18 長度是18
2 增加(從右邊增加)--沒有就新建
r.rpush("foo_list1",2,3,4) 在列表的右邊,依次添加2,3,4
print(r.lrange("foo_list1",0,-1))
['22', '11', '22', '11', '22', '11', '22', '11', '22', '11', '22',
'11', '22', '11', '22', '11', '22', '11', '2', '3', '4']
切片取出值,范圍是索引號0-最后一個元素
print(r.llen("foo_list1")) 21 列表長度是21
3 往已經有的name的列表的左邊添加元素,沒有的話無法創建
lpushx(name,value)
在name對應的list中添加元素,只有name已經存在時,值添加到列表的最左邊
更多:
rpushx(name, value) 表示從右向左操作
r.lpushx("foo_list2",1) 這里"foo_list2"不存在
print(r.lrange("foo_list2",0,-1)) []
print(r.llen("foo_list2")) 0
r.lpushx("foo_list1",1) 這里"foo_list1"之前已經存在,往列表最左邊添加一個元素,一次只能添加一個
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素
['1', '22', '11', '22', '11', '22', '11', '22', '11', '22',
'11', '22', '11', '22', '11', '22', '11', '22', '11', '2', '3', '4']
print(r.llen("foo_list1")) 22 列表長度是22
4 往已經有的name的列表的右邊添加元素,沒有的話無法創建
r.rpushx("foo_list1",1) 這里"foo_list1"之前已經存在,往列表最右邊添加一個元素,一次只能添加一個
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素
['1', '22', '11', '22', '11', '22', '11', '22', '11', '22',
'11', '22', '11', '22', '11', '22', '11', '22', '11', '2', '3', '4','1']
print(r.llen("foo_list1")) 23 列表長度是23
5 新增(固定索引號位置插入元素)
linsert(name, where, refvalue, value))
在name對應的列表的某一個值前或后插入一個新值
參數:
name,redis的name
where,BEFORE或AFTER
refvalue,標桿值,即:在它前后插入數據
value,要插入的數據
r.linsert("foo_list1","before","22","33") 往列表中左邊第一個出現的元素"22"前插入元素"33"
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素
['1', '33', '22', '11', '22', '11', '22', '11', '22',
'11', '22', '11', '22', '11', '22', '11', '22', '11', '22', '11', '2', '3', '4', '1']
print(r.llen("foo_list1")) 24 列表長度是24
6 修改(指定索引號進行修改)
r.lset(name, index, value)
對name對應的list中的某一個索引位置重新賦值
參數:
name,redis的name
index,list的索引位置
value,要設置的值
r.lset("foo_list1",4,44) 把索引號是4的元素修改成44
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素
print(r.llen("foo_list1")) 24 列表長度是24
7 刪除(指定值進行刪除)
r.lrem(name, value, num)
在name對應的list中刪除指定的值
參數:
name,redis的name
value,要刪除的值
num, num=0,刪除列表中所有的指定值;
num=2,從前到后,刪除2個; num=1,從前到后,刪除左邊第1個
num=-2,從后向前,刪除2個
r.lrem("foo_list1","2",1) 將列表中左邊第一次出現的"2"刪除
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素
['1', '33', '22', '11', '44', '11', '22', '11', '22', '11', '22', '11',
'22', '11', '22', '11', '22', '11', '22', '11', '3', '4', '1']
print(r.llen("foo_list1")) 23 列表長度是23
r.lrem("foo_list1","11",0) 將列表中所有的"11"刪除
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素
['1', '33', '22', '44', '22', '22', '22', '22', '22', '22', '22', '3', '4', '1']
print(r.llen("foo_list1")) 14 列表長度是14
8 刪除並返回
lpop(name)
在name對應的列表的左側獲取第一個元素並在列表中移除,返回值則是第一個元素
更多:
rpop(name) 表示從右向左操作
print(r.lpop("foo_list1")) 刪除最左邊的22,並且返回刪除的值22
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素
['44', '22', '22', '22', '22', '22', '22', '22', '3', '4', '1']
print(r.llen("foo_list1")) 11 列表長度是11
print(r.rpop("foo_list1")) 刪除最右邊的1,並且返回刪除的值1
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素
['44', '22', '22', '22', '22', '22', '22', '22', '3', '4']
print(r.llen("foo_list1")) 10 列表長度是10
9 刪除索引之外的值
ltrim(name, start, end)
在name對應的列表中移除沒有在start-end索引之間的值
參數:
name,redis的name
start,索引的起始位置
end,索引結束位置
r.ltrim("foo_list1",0,8) 刪除索引號是0-8之外的元素,值保留索引號是0-8的元素
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素(這里是包含最后一個元素的,是左閉右閉)
['44', '22', '22', '22', '22', '22', '22', '22', '3']
10 取值(根據索引號取值)
lindex(name, index)
在name對應的列表中根據索引獲取列表元素
print(r.lindex("foo_list1",0)) 44 取出索引號是0的值
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素(這里是包含最后一個元素的,是左閉右閉)
['44', '22', '22', '22', '22', '22', '22', '22', '3', '4']
11 移動 元素從一個列表移動到另外一個列表
rpoplpush(src, dst)
從一個列表取出最右邊的元素,同時將其添加至另一個列表的最左邊
參數:
src,要取數據的列表的name
dst,要添加數據的列表的name
r.rpoplpush("foo_list1","foo_list2")
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素(這里是包含最后一個元素的,是左閉右閉)
['44', '22', '22', '22', '22', '22', '22']
print(r.lrange("foo_list2",0,-1)) 切片取出值,范圍是索引號0-最后一個元素(這里是包含最后一個元素的,是左閉右閉)
['22', '3']
12 移動 元素從一個列表移動到另外一個列表 可以設置超時
brpoplpush(src, dst, timeout=0)
從一個列表的右側移除一個元素並將其添加到另一個列表的左側
參數:
src,取出並要移除元素的列表對應的name
dst,要插入元素的列表對應的name
timeout,當src對應的列表中沒有數據時,阻塞等待其有數據的超時時間(秒),0 表示永遠阻塞
r.brpoplpush("foo_list2","foo_list1",timeout=2)
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素(這里是包含最后一個元素的,是左閉右閉)
['22', '3', '44', '22', '22', '22', '22', '22', '22']
print(r.lrange("foo_list2",0,-1)) 切片取出值,范圍是索引號0-最后一個元素(這里是包含最后一個元素的,是左閉右閉)
[]
13 一次移除多個列表
blpop(keys, timeout)
將多個列表排列,按照從左到右去pop對應列表的元素
參數:
keys,redis的name的集合
timeout,超時時間,當元素所有列表的元素獲取完之后,阻塞等待列表內有數據的時間(秒), 0 表示永遠阻塞
更多:
r.brpop(keys, timeout),從右向左獲取數據
r.blpop("foo_list1",timeout=2)
print(r.lrange("foo_list1",0,-1)) 切片取出值,范圍是索引號0-最后一個元素(這里是包含最后一個元素的,是左閉右閉)
['22', '3', '44', '22', '22', '22', '22', '22', '22']
print(r.lrange("foo_list2",0,-1)) 切片取出值,范圍是索引號0-最后一個元素(這里是包含最后一個元素的,是左閉右閉)
14 自定義增量迭代
由於redis類庫中沒有提供對列表元素的增量迭代,如果想要循環name對應的列表的所有元素,那么就需要:
1、獲取name對應的所有列表
2、循環列表
但是,如果列表非常大,那么就有可能在第一步時就將程序的內容撐爆,所有有必要自定義一個增量迭代的功能:
def list_iter(name):
"""
自定義redis列表增量迭代
:param name: redis中的name,即:迭代name對應的列表
:return: yield 返回 列表元素
"""
list_count = r.llen(name)
for index in xrange(list_count):
yield r.lindex(name, index)
使用
for item in list_iter('foo_list1'): ['3', '44', '22', '22', '22'] 遍歷這個列表
print item
6 redis基本命令_set
import redis 導入redis模塊,通過python操作redis 也可以直接在redis主機的服務端操作緩存數據庫
pool = redis.ConnectionPool(host='192.168.19.130', port=6379)
host是redis主機,需要redis服務端和客戶端都起着 redis默認端口是6379
r = redis.Redis(connection_pool=pool) 創建實例
Set操作,Set集合就是不允許重復的列表
1 新增
sadd(name,values)
name對應的集合中添加元素
r.sadd("foo_set1",33,44,55,66) 往集合中添加一個元素 11
print(r.smembers("foo_set1")) set(['11']) 獲取集合中所有的成員
print(r.scard("foo_set1")) 1 集合的長度是1
r.sadd("foo_set2",66,77) 往集合中添加2個元素 22,33
print(r.smembers("foo_set2")) set(['22',"33"]) 獲取集合中所有的成員
print(r.scard("foo_set2")) 2 集合的長度是2
2 獲取元素個數 類似於len
scard(name)
獲取name對應的集合中元素個數
3 獲取集合中所有的成員
smembers(name)
獲取name對應的集合的所有成員
3-1 獲取集合中所有的成員--元組形式
sscan(name, cursor=0, match=None, count=None)
print(r.sscan("foo_set1")) (0L, ['11', '22', '33', '55'])
3-2 獲取集合中所有的成員--迭代器的方式
sscan_iter(name, match=None, count=None)
同字符串的操作,用於增量迭代分批獲取元素,避免內存消耗太大
for i in r.sscan_iter("foo_set1"):
print(i)
4 差集
sdiff(keys, *args)
在第一個name對應的集合中且不在其他name對應的集合的元素集合
print(r.sdiff("foo_set1","foo_set2")) set(['11']) 在集合foo_set1但是不在集合foo_set2中
print(r.smembers("foo_set1")) set(['22',"11"]) 獲取集合中所有的成員
print(r.smembers("foo_set2")) set(['22',"33"]) 獲取集合中所有的成員
5 差集--差集存在一個新的集合中
sdiffstore(dest, keys, *args)
獲取第一個name對應的集合中且不在其他name對應的集合,再將其新加入到dest對應的集合中
r.sdiffstore("foo_set3","foo_set1","foo_set2")
print(r.smembers("foo_set1")) set(['22',"11"]) 獲取集合1中所有的成員
print(r.smembers("foo_set2")) set(['22',"33"]) 獲取集合2中所有的成員
print(r.smembers("foo_set3")) set(['11']) 獲取集合3中所有的成員
6 交集
sinter(keys, *args)
獲取多一個name對應集合的交集
print(r.sinter("foo_set1","foo_set2")) set(['22']) 取2個集合的交集
print(r.smembers("foo_set1")) set(['22',"11"]) 獲取集合1中所有的成員
print(r.smembers("foo_set2")) set(['22',"33"]) 獲取集合2中所有的成員
7 交集--交集存在一個新的集合中
sinterstore(dest, keys, *args)
獲取多一個name對應集合的並集,再將其加入到dest對應的集合中
r.sinterstore("foo_set3","foo_set1","foo_set2")
print(r.smembers("foo_set1")) set(['22',"11"]) 獲取集合1中所有的成員
print(r.smembers("foo_set2")) set(['22',"33"]) 獲取集合2中所有的成員
print(r.smembers("foo_set3")) set(['22']) 獲取集合3中所有的成員
7-1 並集
sunion(keys, *args)
獲取多個name對應的集合的並集
print(r.sunion("foo_set1","foo_set2")) set(['11', '22', '33', '77', '55', '66'])
print(r.smembers("foo_set1")) set(['11', '33', '22', '55']) 獲取集合1中所有的成員
print(r.smembers("foo_set2")) set(['33', '77', '66', '22']) 獲取集合2中所有的成員
7-2 並集--並集存在一個新的集合
sunionstore(dest,keys, *args)
獲取多一個name對應的集合的並集,並將結果保存到dest對應的集合中
r.sunionstore("foo_bingji","foo_set1","foo_set2")
print(r.smembers("foo_set1")) set(['11', '33', '22', '55']) 獲取集合1中所有的成員
print(r.smembers("foo_set2")) set(['33', '77', '66', '22']) 獲取集合2中所有的成員
print(r.smembers("foo_bingji")) set(['11', '22', '33', '77', '55', '66'])
8 判斷是否是集合的成員 類似in
sismember(name, value)
檢查value是否是name對應的集合的成員
print(r.sismember("foo_set1",11)) True 11是集合的成員
print(r.sismember("foo_set1","11")) True
print(r.sismember("foo_set1",23)) False 23不是集合的成員
9 移動
smove(src, dst, value)
將某個成員從一個集合中移動到另外一個集合
r.smove("foo_set1","foo_set4",11)
print(r.smembers("foo_set1")) set(['22',"11"]) 獲取集合1中所有的成員
print(r.smembers("foo_set4")) set(['22',"33"]) 獲取集合4中所有的成員
10 刪除--隨機刪除並且返回被刪除值
spop(name)
從集合移除一個成員,並將其返回,說明一下,集合是無序的,所有是隨機刪除的
print(r.smembers("foo_set1")) set(['11', '22', '33', '44', '55', '66']) 獲取集合1中所有的成員
print(r.spop("foo_set1")) 44 (這個刪除的值是隨機刪除的,集合是無序的)
print(r.smembers("foo_set1")) set(['11', '33', '66', '22', '55']) 獲取集合1中所有的成員
11 刪除--指定值刪除
srem(name, values)
在name對應的集合中刪除某些值
print(r.smembers("foo_set1")) set(['11', '33', '66', '22', '55'])
r.srem("foo_set1",66) 從集合中刪除指定值 66
print(r.smembers("foo_set1")) set(['11', '33', '22', '55'])
12 隨機獲取多個集合的元素
srandmember(name, numbers)
從name對應的集合中隨機獲取 numbers 個元素
print(r.srandmember("foo_set1",3)) ['33', '55', '66'] 隨機獲取3個元素
print(r.smembers("foo_set1")) set(['11', '33', '66', '22', '55'])
07 redis基本命令_有序set
import redis 導入redis模塊,通過python操作redis 也可以直接在redis主機的服務端操作緩存數據庫
pool = redis.ConnectionPool(host='192.168.19.130', port=6379)
host是redis主機,需要redis服務端和客戶端都起着 redis默認端口是6379
r = redis.Redis(connection_pool=pool) 創建實例
Set操作,Set集合就是不允許重復的列表,本身是無序的
有序集合,在集合的基礎上,為每元素排序;元素的排序需要根據另外一個值來進行比較,
所以,對於有序集合,每一個元素有兩個值,即:值和分數,分數專門用來做排序。
1 新增
zadd(name, *args, **kwargs)
在name對應的有序集合中添加元素
如:
zadd('zz', 'n1', 1, 'n2', 2)
或
zadd('zz', n1=11, n2=22)
r.zadd("foo_zset1",n3=11,n4=22)
r.zadd("foo_zset2",n3=11,n4=23)
print(r.zcard("foo_zset1")) 2 長度是2 2個元素
print(r.zrange("foo_zset1",0,-1)) ['n1', 'n2'] 獲取有序集合中所有元素
print(r.zrange("foo_zset1",0,-1,withscores=True)) [('n1', 11.0), ('n2', 22.0)] 獲取有序集合中所有元素和分數
2 獲取有序集合元素個數 類似於len
zcard(name)
獲取name對應的有序集合元素的數量
3 獲取有序集合的所有元素
r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
按照索引范圍獲取name對應的有序集合的元素
參數:
name,redis的name
start,有序集合索引起始位置(非分數)
end,有序集合索引結束位置(非分數)
desc,排序規則,默認按照分數從小到大排序
withscores,是否獲取元素的分數,默認只獲取元素的值
score_cast_func,對分數進行數據轉換的函數
更多:
從大到小排序
zrevrange(name, start, end, withscores=False, score_cast_func=float)
按照分數范圍獲取name對應的有序集合的元素
zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
從大到小排序
zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)
3-1 從大到小排序
zrevrange(name, start, end, withscores=False, score_cast_func=float)
print(r.zrevrange("foo_zset1",0,-1)) ['n2', 'n1'] 只獲取元素,不顯示分數
print(r.zrevrange("foo_zset1",0,-1,withscores=True)) [('n2', 22.0), ('n1', 11.0)]
獲取有序集合中所有元素和分數,安裝分數倒序
3-2 按照分數范圍獲取name對應的有序集合的元素
zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
print(r.zrangebyscore("foo_zset1",15,25)) ['n2']
print(r.zrangebyscore("foo_zset1",12,22, withscores=True)) [('n2', 22.0)]
在分數是12-22之間(左閉右閉),取出符合條件的元素
3-3 從大到小排序
zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)
print(r.zrevrangebyscore("foo_zset1",22,11,withscores=True)) [('n2', 22.0), ('n1', 11.0)]
在分數是22-11之間(左閉右閉),取出符合條件的元素 按照分數倒序
3-4 獲取所有元素--默認按照分數順序排序
zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
print(r.zscan("foo_zset1")) (0L, [('n3', 11.0), ('n4', 22.0), ('n2', 30.0)])
3-5 獲取所有元素--迭代器
zscan_iter(name, match=None, count=None,score_cast_func=float)
for i in r.zscan_iter("foo_zset1"): 遍歷迭代器
print(i)
('n3', 11.0)
('n4', 22.0)
('n2', 30.0)
4 zcount(name, min, max)
獲取name對應的有序集合中分數 在 [min,max] 之間的個數
print(r.zrange("foo_zset1",0,-1,withscores=True)) [('n1', 11.0), ('n2', 22.0)]
print(r.zcount("foo_zset1",11,22)) 2
5 自增
zincrby(name, value, amount)
自增name對應的有序集合的 name 對應的分數
r.zincrby("foo_zset1","n2",amount=2) 每次將n2的分數自增2
print(r.zrange("foo_zset1",0,-1,withscores=True)) [('n1', 11.0), ('n2', 30.0)]
6 獲取值的索引號
zrank(name, value)
獲取某個值在 name對應的有序集合中的排行(從 0 開始)
更多:
zrevrank(name, value),從大到小排序
print(r.zrange("foo_zset1",0,-1,withscores=True)) [('n1', 11.0), ('n2', 30.0)]
print(r.zrank("foo_zset1","n1")) 0 n1的索引號是0 這里按照分數順序(從小到大)
print(r.zrank("foo_zset1","n2")) 1 n2的索引號是1
print(r.zrevrank("foo_zset1","n1")) 1 n1的索引號是1 這里安照分數倒序(從大到小)
7 刪除--指定值刪除
zrem(name, values)
刪除name對應的有序集合中值是values的成員
如:zrem('zz', ['s1', 's2'])
print(r.zrange("foo_zset1",0,-1,withscores=True))
r.zrem("foo_zset2","n3") 刪除有序集合中的元素n1 刪除單個
print(r.zrange("foo_zset1",0,-1,withscores=True))
8 刪除--根據排行范圍刪除,按照索引號來刪除
zremrangebyrank(name, min, max)
根據排行范圍刪除
print(r.zrange("foo_zset1",0,-1,withscores=True)) [('n3', 11.0), ('n4', 22.0), ('n2', 30.0)]
r.zremrangebyrank("foo_zset1",0,1) 刪除有序集合中的索引號是0,1的元素
print(r.zrange("foo_zset1",0,-1,withscores=True)) [('n2', 30.0)]
9 刪除--根據分數范圍刪除
zremrangebyscore(name, min, max)
根據分數范圍刪除
print(r.zrange("foo_zset1",0,-1,withscores=True)) [('n3', 11.0), ('n4', 22.0), ('n2', 30.0)]
r.zremrangebyscore("foo_zset1",11,22) 刪除有序集合中的分數是11-22的元素
print(r.zrange("foo_zset1",0,-1,withscores=True)) [('n2', 30.0)]
10 獲取值對應的分數
zscore(name, value)
獲取name對應有序集合中 value 對應的分數
print(r.zrange("foo_zset1",0,-1,withscores=True)) [('n3', 11.0), ('n4', 22.0), ('n2', 30.0)]
print(r.zscore("foo_zset1","n3")) 11.0 獲取元素n3對應的分數11.0
import redis 導入redis模塊,通過python操作redis 也可以直接在redis主機的服務端操作緩存數據庫
pool = redis.ConnectionPool(host='192.168.19.130', port=6379)
host是redis主機,需要redis服務端和客戶端都起着 redis默認端口是6379
r = redis.Redis(connection_pool=pool) 創建實例
08 其他常用操作
1 刪除
delete(*names)
根據刪除redis中的任意數據類型(string、hash、list、set、有序set)
1-1刪除string
r.set('foo', 'Bar')
print(r.strlen("foo")) 3 3ge 字節
print(r.getrange("foo",0,-1)) Bar
r.delete("foo") 刪除字符串類型的foo
print(r.get("foo")) None
print(r.getrange("foo",0,-1))
print(r.strlen("foo")) 0 0個字節
1-2 刪除hash
r.hset("foo_hash4","k1","v1")
print(r.hscan("foo_hash4")) (0L, {'k1': 'v1'})
r.delete("foo_hash4") 刪除hash類型的鍵值對
print(r.hscan("foo_hash4")) (0L, {})
2 檢查名字是否存在
exists(name)
檢測redis的name是否存在
print(r.exists("foo_hash4")) True 存在就是True
print(r.exists("foo_hash5")) False 不存在就是False
2-1
r.lpush("foo_list5",11,22)
print(r.lrange("foo_list5",0,-1)) ['22', '11', '22', '11']
print(r.exists("foo_list5")) True 存在就是True
print(r.exists("foo_list6")) False 不存在就是False
3 模糊匹配
keys(pattern='*')
根據模型獲取redis的name
更多:
KEYS * 匹配數據庫中所有 key 。
KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
KEYS h*llo 匹配 hllo 和 heeeeello 等。
KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo
print(r.keys("foo*"))
['foo_hash1', 'foo_bingji', 'foo_list1', 'foo_list2', 'foo3', 'foo_set2', 'foo_hash4', 'foo_zset2',
'foo2', 'foo4', 'foo_set1', 'foo_zset1', 'foo_hash2', 'foo1', 'foo_list5', 'foo_set3']
4 設置超時時間
expire(name ,time)
為某個redis的某個name設置超時時間
r.lpush("foo_list5",11,22)
r.expire("foo_list5",time=10)
print(r.lrange("foo_list5",0,-1))
5 重命名
rename(src, dst)
對redis的name重命名為
r.rename("foo_list6","foo_list5")
print(r.lrange("foo_list5",0,-1)) ['22', '11']
print(r.lrange("foo_list6",0,-1)) []
6 隨機獲取name
randomkey()
隨機獲取一個redis的name(不刪除)
print(r.keys("foo*"))
['foo_set1', 'foo3', 'foo_set2', 'foo_zset2', 'foo4', 'foo_zset1', 'foo_list5', 'foo2',
'foo_hash2', 'foo1', 'foo_set3', 'foo_hash1', 'foo_hash4', 'foo_list2', 'foo_bingji']
print(r.randomkey()) foo_hash2 隨機獲取一個name
7 獲取類型
type(name)
獲取name對應值的類型
print(r.type("foo_hash2")) hash
print(r.type("foo_set1")) set
print(r.type("foo3")) string
8 查看所有元素
scan(cursor=0, match=None, count=None)
print(r.hscan("foo_hash2")) (0L, {'k3': 'v3', 'k2': 'v2'})
print(r.sscan("foo_set3")) (0L, ['22'])
print(r.zscan("foo_zset2")) (0L, [('n4', 23.0)])
print(r.getrange("foo1",0,-1)) 121 --字符串
print(r.lrange("foo_list5",0,-1)) ['22', '11'] --列表
9 查看所有元素--迭代器
scan_iter(match=None, count=None)
for i in r.hscan_iter("foo_hash2"):--遍歷
print(i)
('k3', 'v3')
('k2', 'v2')
for i in r.sscan_iter("foo_set3"):
print(i) 22
for i in r.zscan_iter("foo_zset2"):
print(i) ('n4', 23.0)
__author__ = 'Administrator'
-*- coding:utf-8 -*-
管道
redis-py默認在執行每次請求都會創建(連接池申請連接)和斷開(歸還連接池)一次連接操作,
如果想要在一次請求中指定多個命令,則可以使用pipline實現一次請求指定多個命令,並且默認情況下一次pipline 是原子性操作。
import redis
pool = redis.ConnectionPool(host='192.168.19.130', port=6379)
r = redis.Redis(connection_pool=pool)
pipe = r.pipeline(transaction=False)
pipe = r.pipeline(transaction=True)
r.set('name', 'jack')
r.set('role', 'sb')
pipe.execute()
print(r.get("name")) jack
print(r.get("role")) sb