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"))