這里的一切討論均基於python的redis-py庫。
安裝使用:
pip install redis
然后去獲取一個redis客戶端:
redis_conn = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB)
redis有五種基本類型。包括字符串類型、散列類型、列表類型、集合類型、有序集合類型。每種不同的類型,reids客戶端提供了很多不同的操作方法,下面我將記錄下平時最常用的一些基於python的操作。。主要是為了方便查閱,因為很久不用又忘記,每次查閱太慢成本太高這種事情本來坐起來就應該無腦又高效,好開始。
注:以下將我上面得到的客戶端redis_conn賦值給x,下面x代表python redis客戶端。
字符串類型:
In [15]: x.set("foo", 1)
True
In [16]: x.get("foo")
'1'
In [17]: x.set("foo", "today I want to apologize to myself")
True
In [18]: x.get("foo")
'today I want to apologize to myself'
# 因為和python里面的關鍵字del沖突,所以這里python的客戶端redis-py是用了delete替代del作為刪除的關鍵字
In [19]: x.delete("foo")
1
In [20]: x
Redis<ConnectionPool<Connection<host=devdb,port=6379,db=0>>>
In [21]: x.get("foo")
字符串的增刪改查的方法都非常簡單。特別注意的是,當你調用刪除delete方法的時候返回的是操作成功了多少個對象。另外還有一個遞增key的值的操作,但是我覺得只要不拿redis當數據庫使用基本上很難用上但是這里也介紹一下:
In [27]: x.incr("num") 1 In [28]: x.incr("num") 2 In [29]: x.incr("num") 3 In [30]: x.incr("num") 4
當key num還沒有被set的時候直接使用incr函數可以直接將其置為1,然后再調用會依次遞增,而且這個操作是原子操作所以不會出現競態條件。一般可以用來記錄一下訪問次數打點什么的,速度也比往數據庫直接插來得要快。當然字符串還涉及到一套二進制的操作方法,包括get\set方法等,由於不常用所以這里就不記錄了,有興趣可以自己去查一下。
散列類型:
首先直接展示最簡單的,設置一個car鍵的字典為{"price": 400} 然后使用hget方法去得到這個鍵下面對應的字段的值。
In [44]: x.hset("car", "price", 400) 1L In [45]: x.hget("car", "price") '400'
下面要展示判斷鍵和鍵值是否存在:
# 判斷鍵是否存在 In [47]: x.exists("car") True In [48]: x.exists("m") False # 判斷鍵值是否存在 In [50]: x.hexists("car", "price") True In [51]: x.hexists("car", "name") False
當字段不存在的時候才賦值:
In [52]: x.hsetnx("car", "name", "hahaha") 1L In [53]: x.hsetnx("car", "name", "hahaha") 0L In [54]: x.hsetnx("car", "name", "xixiix") 0L In [56]: x.hget("car", "name") 'hahaha'
可以看到,當鍵為car的屬性name不存在的時候第一個操作成功了,但是第二次執行同樣的操作就失敗了。這是因為hsetnx只是當字段不存在的時候才賦值。成功之后返回被影響的條數。當數據存在的時候,使用hsetnx是無法修改值的。
查看某個鍵下面的全部屬性和值可以使用hkeys 和 hval或者使用hlen查看鍵的屬性數量:
In [58]: x.hkeys("car") ['price', 'name'] In [59]: x.hvals("car") ['400', 'hahaha']
In [60]: x.hlen("car")
2
列表類型:
redis的列表實現使用了一個雙端鏈表,所以redis的列表類型支持從左右兩邊插入數據。由於是雙端鏈表所以不管從哪邊插入或者查詢的效率跟列表本身多大是沒有關系的。
下面演示插入和彈出和索引數據:
In [61]: x.lpush("challenge", 1) 1L In [62]: x.rpush("challenge", 2) 2L In [63]: x.lrange("challenge", 0, 20) ['1', '2'] In [64]: x.lpop("challenge") '1' In [65]: x.rpop("challenge") '2' In [66]: x.lrange("challenge", 0, 20) []
這里展示了插入彈出還有索引數組數據需要使用到的方法,其實還有llen,llen方法可以直接拿到該數組有多少個的存在,而且算法時間復雜度是O(1),因為是常量讀取,而並不是傳統關系數據庫一樣的需要去計算。
下面單獨說說lrange這個命令,也就是操作列表數據讀取的命令,除了剛才上面展示的用法,lrange還支持負索引,要是你是python的玩家的話會不會覺得特別親切?但是這里的負索引並不能逆向列表。下面演示一下:
In [77]: x.lrange("challenge", 0, 20) ['8', '7', '6', '5', '4', '3', '2', '1'] In [81]: x.lrange("challenge", -20, -1) ['8', '7', '6', '5', '4', '3', '2', '1']
另外刪除方法有點類似於python里面的remove方法,是查找對應的值刪除,而不是索引刪除這里要注意而且這個查找在列表大了之后效率會很低:
In [101]: x.lrange("challenge", 0, -1) ['8', '7', '6', '5', '4', '3', '2'] In [102]: x.lrem("challenge", 4) 1L In [103]: x.lrange("challenge", 0, -1) ['8', '7', '6', '5', '3', '2']
還有一批基於列表索引操作的命令:
In [103]: x.lrange("challenge", 0, -1) ['8', '7', '6', '5', '3', '2'] In [104]: x.lindex("challenge", 1) '7' In [105]: x.lindex("challenge", 2) '6'
In [109]: x.lset("challenge", 1, 22)
True
In [110]: x.lrange("challenge", 0, -1)
['8', '22', '6', '5', '3', '2']
除了這里的索引操作賦值和看對應索引上的值以外,還有幾個比較特別一點的操作功能不過也不是太常用 這里介紹一下:
# 只保留這個列表區間里面的值 In [112]: x.ltrim("challenge", 0, 4) True In [113]: x.lrange("challenge",0, -1) ['8', '22', '6', '5', '3'] # 列表中插入元素 In [131]: x.lrange("challenge", 0, -1) ['8', '22', '6', '5', '3'] In [132]: x.linsert("challenge", "before", 22, 3) 6 In [133]: x.lrange("challenge", 0, -1) ['8', '3', '22', '6', '5', '3']
這里要注意linsert方法的第三個參數,是查找第一個符合條件的數值並向他的第二個參數(前面或者后面)插入元素。
Reference:
http://www.cnblogs.com/melonjiang/p/5342505.html Python操作redis