七個原則

  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 不好玩的開發模式。

String 類型及操作

String 是最簡單的類型,一個 key 對應一個 value。

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。

常用命令及操作

set

設置 key 對應的值為 string 類型的 value。

例如:我們添加一個 name=Jacob 的鍵值對,可以這樣做:

127.0.0.1:6379> set name Jacob
OK
setnx

設置 key 對應的值為 string 類型的 value。 如果 key 已經存在,返回 0, nx 是 not exist 的意思。

例如:我們添加一個 name=Jacob 的鍵值對,可以這樣做:

127.0.0.1:6379> get name
"Jacob"
127.0.0.1:6379> setnx name Jacob
(integer) 0

由于原來 name 有一個對應的值,所以本次的修改不生效,且返回碼是 0。

setex

設置 key 對應的值為 string 類型的 value,并指定此鍵值對應的有效期。
例如:我們添加一個 haircolor= red 的鍵值對,并指定它的有效期是 10 秒,可以這樣做:

127.0.0.1:6379> setex color 10 red
OK
127.0.0.1:6379> get color
"red"
127.0.0.1:6379> get color
(nil)

可見由于最后一次的調用是 10 秒以后了,所以取不到 haicolor 這個鍵對應的值。

setrange

設置指定 key 的 value 值的子字符串。
例如我們希望將 HongWan 的 126 郵箱替換為 gmail 郵箱,那么我們可以這樣做:

127.0.0.1:6379> setrange name 5 @jacob.com
(integer) 15
127.0.0.1:6379> get name
"Jacob@jacob.com"

其中的 8 是指從下標為 8(包含 8)的字符開始替換

mset

一次設置多個 key 的值,成功返回 ok 表示所有的值都設置了,失敗返回 0 表示沒有任何值被設置。

127.0.0.1:6379> mset name1 Jacob1 name2 Jacob2
OK
127.0.0.1:6379> get name1
"Jacob1"
127.0.0.1:6379> get name2
"Jacob2"
msetnx

一次設置多個 key 的值,成功返回 ok 表示所有的值都設置了,失敗返回 0 表示沒有任何值被設置, 但是不會覆蓋已經存在的 key。

127.0.0.1:6379> get name1
"Jacob1"
127.0.0.1:6379> get name2
"Jacob2"
127.0.0.1:6379> msetnx name2 Jacob2 name3 Jacob3
(integer) 0
127.0.0.1:6379> get name2
"Jacob2"
127.0.0.1:6379> get name3
(nil)

可以看出如果這條命令返回 0,那么里面操作都會回滾,都不會被執行。(原子性)

get

獲取 key 對應的 string 值,如果 key 不存在返回 nil。
例如我們獲取一個庫中存在的鍵 name,可以很快得到它對應的 value

127.0.0.1:6379> get name
"Jacob"
127.0.0.1:6379> get name3
(nil)

nil:表示無此鍵值對。

getset

設置 key 的值,并返回 key 的舊值。 如果 key 不存在,那么將返回 nil。

127.0.0.1:6379> get name
"Jacob@jacob.com"
127.0.0.1:6379> getset name Jacob_new
"Jacob@jacob.com"
127.0.0.1:6379> get name
"Jacob_new"
127.0.0.1:6379> getset name4 Jacob4
(nil)
getrange

獲取指定 key 的 value 值的子字符串。

127.0.0.1:6379> get name
"Jacob_new"
127.0.0.1:6379> getrange name 0 1
"Ja"

字符串左面下標是從 0 開始的。

127.0.0.1:6379> getrange name -3 -1
"new"

字符串右面下標是從-1 開始的。

127.0.0.1:6379> getrange name 6 10
"new"

當下標超出字符串長度時,將默認為是同方向的最大下標。

mget

一次獲取多個 key 的值,如果對應 key 不存在,則對應返回 nil。

127.0.0.1:6379> mget name name2 name3
1) "Jacob_new"
2) "Jacob2"
3) (nil)

name3 由于沒有這個鍵定義,所以返回 nil。

incr

對 key 的值做加加操作,并返回新的值。注意 incr 一個不是 int 的 value 會返回錯誤, incr 一個不存在的 key,則設置 key 為 1

127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> incr age
(integer) 19
incrby

同 incr 類似,加指定值 , key 不存在時候會設置 key,并認為原來的 value 是 0

127.0.0.1:6379> get age
"19"
127.0.0.1:6379> incrby age 6
(integer) 25
decr

對 key 的值做的是減減操作, decr 一個不存在 key,則設置 key 為-1

127.0.0.1:6379> get age
"25"
127.0.0.1:6379> decr age
(integer) 24
127.0.0.1:6379> get age
"24"
decrby

同 decr,減指定值。

127.0.0.1:6379> get age
"24"
127.0.0.1:6379> decrby age 6
(integer) 18
127.0.0.1:6379> get age
"18"
append

給指定 key 的字符串值追加 value,返回新字符串值的長度。
例如:我們向 name 的值追加一個@126.com 字符串,那么可以這樣做:

127.0.0.1:6379> append name @jacob.com
(integer) 19
127.0.0.1:6379> get name
"Jacob_new@jacob.com"
strlen

取指定 key 的 value 值的長度。

127.0.0.1:6379> get name
"Jacob_new@jacob.com"
127.0.0.1:6379> strlen name
(integer) 19

hashes 類型及操作