標籤:
Redis的作者antirez(Salvatore Sanfilippo)曾經發表了一篇名為Redis宣言(Redis Manifesto)的文章,文中列舉了Redis 的七個原則,以向大家闡明Redis 的思想。
1、Redis是一個操作資料結構的語言工具,它提供基於TCP的協議以操作豐富的資料結構。在Redis中,資料結構這個詞的意義不僅表示在某種資料結構上的操作,更包括了結構本身及這些操作的時間空間複雜度。
2、Redis定位於一個記憶體資料庫,正是由於記憶體的快速存取特性,才使得Redis能夠有如此高的效能,才使得Redis能夠輕鬆處理大量複雜的資料結構,Redis會嘗試其它的儲存方面的選擇,但是永遠不會改變它是一個記憶體資料庫的角色。
3、Redis使用基礎的API操作基礎的資料結構,Redis的API與資料結構一樣,都是一些最基礎的元素,你幾乎可以將任何資訊互動使用此API格式表示。作者調侃說,如果有其它非人類的智能生物存在,他們也能理解Redis的API。因為它是如此的基礎。
4、Redis有著詩一般優美的代碼,經常有一些不太瞭解Redis 有的人會建議Redis採用一些其它人的代碼,以實現一些Redis 未實現的功能,但這對我們來說就像是非要給《紅樓夢》接上後四十回一樣。
5、Redis始終避免複雜化,我們認為設計一個系統的本質,就是與複雜化作戰。我們不會為了一個小功能而往源碼裡添加上千行代碼,解決複雜問題的方法就是讓複雜問題永遠不要提複雜的問題。
6、Redis支援兩個層成的API,第一個層麵包含部分操作API,但它支援用於分布式環境下的Redis。第二個層面的API支援更複雜的multi-key操作。它們各有所長,但是我們不會推出兩者都支援的API,但我們希望能夠提供執行個體間資料移轉的命令,並執行multi-key操作。
7、我們以最佳化代碼為樂,我們相信編碼是一件辛苦的工作,唯一對得起這辛苦的就是去享受它。如果我們在編碼中失去了樂趣,那最好的解決辦法就是停下來。我們決不會選擇讓Redis不好玩的開發模式。
Redis的作者antirez曾笑稱Redis為一個資料結構伺服器(data structures server),我認為這是一個非常準確的表述,Redis的所有功能就是將資料以其固有的幾種結構來儲存,並提供給使用者操作這幾種結構的介面。本文將介紹Redis支援的各種資料類型及其操作介面。
strings類型及操作
string是最簡單的類型,你可以理解成與Memcached是一模一樣的類型,一個key對應一個value,其上支援的操作與Memcached的操作類似。但它的功能更豐富。
string類型是二進位安全的。意思是redis的string可以包含任何資料,比如jpg圖片或者序列化的對象。從內部實現來看其實string可以看作byte數組,最大上限是1G位元組,下面是string類型的定義:
struct sdshdr {
long len;
long free;
char buf[];
};
len是buf數組的長度。
free是數組中剩餘可用位元組數,由此可以理解為什麼string類型是二進位安全的了,因為它本質上就是個byte數組,當然可以包含任何資料了
buf是個char數組用於存貯實際的字串內容,其實char和c#中的byte是等價的,都是一個位元組。
另外string類型可以被部分命令按int處理.比如incr等命令,如果只用string類型,redis就可以被看作加上持久化特性的memcached。當然redis對string類型的操作比memcached還是多很多的,具體操作方法如下:
1、set
設定key對應的值為string類型的value。
例如我們添加一個name= HongWan的索引值對,可以這樣做:
redis 127.0.0.1:6379> set name HongWan
OK
redis 127.0.0.1:6379>
2、setnx
設定key對應的值為string類型的value。如果key已經存在,返回0,nx是not exist的意思。
例如我們添加一個name= HongWan_new的索引值對,可以這樣做:
redis 127.0.0.1:6379> get name
"HongWan"
redis 127.0.0.1:6379> setnx name HongWan_new
(integer) 0
redis 127.0.0.1:6379> get name
"HongWan"
redis 127.0.0.1:6379>
由於原來name有一個對應的值,所以本次的修改不生效,且返回碼是0。
3、setex
設定key對應的值為string類型的value,並指定此索引值對應的有效期間。
例如我們添加一個haircolor= red的索引值對,並指定它的有效期間是10秒,可以這樣做:
redis 127.0.0.1:6379> setex haircolor 10 red
OK
redis 127.0.0.1:6379> get haircolor
"red"
redis 127.0.0.1:6379> get haircolor
(nil)
redis 127.0.0.1:6379>
可見由於最後一次的調用是10秒以後了,所以取不到haicolor這個鍵對應的值。
4、setrange
設定指定key的value值的子字串。
例如我們希望將HongWan的126郵箱替換為gmail郵箱,那麼我們可以這樣做:
redis 127.0.0.1:6379> get name
"[email protected]"
redis 127.0.0.1:6379> setrange name 8 gmail.com
(integer) 17
redis 127.0.0.1:6379> get name
"[email protected]"
redis 127.0.0.1:6379>
其中的8是指從下標為8(包含8)的字元開始替換
5、mset
一次設定多個key的值,成功返回ok表示所有的值都設定了,失敗返回0表示沒有任何值被設定。
redis 127.0.0.1:6379> mset key1 HongWan1 key2 HongWan2
OK
redis 127.0.0.1:6379> get key1
"HongWan1"
redis 127.0.0.1:6379> get key2
"HongWan2"
redis 127.0.0.1:6379>
6、msetnx
一次設定多個key的值,成功返回ok表示所有的值都設定了,失敗返回0表示沒有任何值被設定,但是不會覆蓋已經存在的key。
redis 127.0.0.1:6379> get key1
"HongWan1"
redis 127.0.0.1:6379> get key2
"HongWan2"
redis 127.0.0.1:6379> msetnx key2 HongWan2_new key3 HongWan3
(integer) 0
redis 127.0.0.1:6379> get key2
"HongWan2"
redis 127.0.0.1:6379> get key3
(nil)
可以看出如果這條命令返回0,那麼裡面操作都會復原,都不會被執行。
7、get
擷取key對應的string值,如果key不存在返回nil。
例如我們擷取一個庫中存在的鍵name,可以很快得到它對應的value
redis 127.0.0.1:6379> get name
"HongWan"
redis 127.0.0.1:6379>
我們擷取一個庫中不存在的鍵name1,那麼它會返回一個nil以表時無此索引值對
redis 127.0.0.1:6379> get name1
(nil)
redis 127.0.0.1:6379>
8、getset
設定key的值,並返回key的舊值。
redis 127.0.0.1:6379> get name
"HongWan"
redis 127.0.0.1:6379> getset name HongWan_new
"HongWan"
redis 127.0.0.1:6379> get name
"HongWan_new"
redis 127.0.0.1:6379>
接下來我們看一下如果key不存的時候會什麼樣兒?
redis 127.0.0.1:6379> getset name1 aaa
(nil)
redis 127.0.0.1:6379>
可見,如果key不存在,那麼將返回nil
9、getrange
擷取指定key的value值的子字串。
具體範例如下:
redis 127.0.0.1:6379> get name
"[email protected]"
redis 127.0.0.1:6379> getrange name 0 6
"HongWan"
redis 127.0.0.1:6379>
字串左面下標是從0開始的
redis 127.0.0.1:6379> getrange name -7 -1
"126.com"
redis 127.0.0.1:6379>
字串右面下標是從-1開始的
redis 127.0.0.1:6379> getrange name 7 100
"@126.com"
redis 127.0.0.1:6379>
當下標超出字串長度時,將預設為是同方向的最大下標
10、mget
一次擷取多個key的值,如果對應key不存在,則對應返回nil。
具體範例如下:
redis 127.0.0.1:6379> mget key1 key2 key3
1) "HongWan1"
2) "HongWan2"
3) (nil)
redis 127.0.0.1:6379>
key3由於沒有這個鍵定義,所以返回nil。
11、incr
對key的值做加加操作,並返回新的值。注意incr一個不是int的value會返回錯誤,incr一個不存在的key,則設定key為1
redis 127.0.0.1:6379> set age 20
OK
redis 127.0.0.1:6379> incr age
(integer) 21
redis 127.0.0.1:6379> get age
"21"
redis 127.0.0.1:6379>
12、incrby
同incr類似,加指定值 ,key不存在時候會設定key,並認為原來的value是 0
redis 127.0.0.1:6379> get age
"21"
redis 127.0.0.1:6379> incrby age 5
(integer) 26
redis 127.0.0.1:6379> get name
"[email protected]"
redis 127.0.0.1:6379> get age
"26"
redis 127.0.0.1:6379>
13、decr
對key的值做的是減減操作,decr一個不存在key,則設定key為-1
redis 127.0.0.1:6379> get age
"26"
redis 127.0.0.1:6379> decr age
(integer) 25
redis 127.0.0.1:6379> get age
"25"
redis 127.0.0.1:6379>
14、decrby
同decr,減指定值。
redis 127.0.0.1:6379> get age
"25"
redis 127.0.0.1:6379> decrby age 5
(integer) 20
redis 127.0.0.1:6379> get age
"20"
redis 127.0.0.1:6379>
decrby完全是為了可讀性,我們完全可以通過incrby一個負值來實現同樣效果,反之一樣。
redis 127.0.0.1:6379> get age
"20"
redis 127.0.0.1:6379> incrby age -5
(integer) 15
redis 127.0.0.1:6379> get age
"15"
redis 127.0.0.1:6379>
15、append
給指定key的字串值追加value,返回新字串值的長度。
例如我們向name的值追加一個@126.com字串,那麼可以這樣做:
redis 127.0.0.1:6379> append name @126.com
(integer) 15
redis 127.0.0.1:6379> get name
"[email protected]"
redis 127.0.0.1:6379>
16、strlen
取指定key的value值的長度。
redis 127.0.0.1:6379> get name
"HongWan_new"
redis 127.0.0.1:6379> strlen name
(integer) 11
redis 127.0.0.1:6379> get age
"15"
redis 127.0.0.1:6379> strlen age
(integer) 2
redis 127.0.0.1:6379>
Redis詳解:strings資料類型及操作