七個原則

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

hashes 類型及操作

Redis hash 是一個 String 類型的 field 和 value 的映射表。它的添加、刪除操作都是 O(1) (平均)。hash 特別適合用于存儲對象。相較于將對象的每個字段存成單個 string 類型。將一個對象存儲在 hash 類型中會占用更少的內存,并且可以更方便的存取整個對象。省內存的原因是新建一個 hash 對象時開始是用 zipmap(又稱為 small hash)來存儲的。這個 zipmap 其實并不是 hash table,但是 zipmap 相比正常的 hash 實現可以節省不少 hash 本身需要的一些元數據存儲開銷。盡管 zipmap 的添加,刪除,查找都是 O(n),但是由于一般對象的 field 數量都不太多。所以使用 zipmap 也是很快的,也就是說添加、刪除平均還是 O(1)。如果 field 或者 value的大小超出一定限制后, Redis 會在內部自動將 zipmap 替換成正常的 hash 實現. 這個限制可以在配置文件中指定。

hash-max-zipmap-entries 64 #配置字段最多 64 個。

hash-max-zipmap-value 512 #配置 value 最大為 512 字節。

常用命令及操作

hset

設置 hash field 為指定值,如果 key 不存在,則先創建。

127.0.0.1:6379> hset myhash name Jacob
(integer) 1
hsetnx

設置 hash field 為指定值,如果 key 不存在,則先創建。 如果 field 已經存在,返回 0, nx 是not exist 的意思。

127.0.0.1:6379> hsetnx myhash age 18
(integer) 1
127.0.0.1:6379> hsetnx myhash age 18
(integer) 0

第一次執行是成功的,但第二次執行相同的命令失敗,原因是 field 已經存在了。

hmset

同時設置 hash 的多個 field。

127.0.0.1:6379> hmset myhash name2 Jacob2 name3 Jacob3
OK
hget

獲取指定的 hash field。

127.0.0.1:6379> hget myhash name
"Jacob"
127.0.0.1:6379> hget myhash name2
"Jacob2"
127.0.0.1:6379> hget myhash name3
"Jacob3"
127.0.0.1:6379> hget myhash name4
(nil)

由于數據庫沒有 field3,所以取到的是一個空值 nil

hmget

獲取全部指定的 hash filed。

127.0.0.1:6379> hmget myhash name name2 name3
1) "Jacob"
2) "Jacob2"
3) "Jacob3"
hincrby

指定的 hash filed 加上給定值。

127.0.0.1:6379> hget myhash age
"18"
127.0.0.1:6379> hincrby myhash age 6
(integer) 24
127.0.0.1:6379> hget myhash age
"24"
hexists

測試指定 field 是否存在。 1表示存在,0表示不存在。

127.0.0.1:6379> hexists myhash name3
(integer) 1
127.0.0.1:6379> hexists myhash name4
(integer) 0
hlen

返回指定 hash 的 field 數量。

127.0.0.1:6379> hlen myhash
(integer) 4

myhash 中有 4 個 field(name,name2,name3,age)。

hkeys

返回 hash 的所有 field。

127.0.0.1:6379> hkeys myhash
1) "name"
2) "age"
3) "nane2"
4) "name3"
hdel

返回指定 hash 的 field 數量。

127.0.0.1:6379> hkeys myhash
1) "name"
2) "age"
3) "nane2"
4) "name3"
127.0.0.1:6379> hdel myhash name3
(integer) 1
127.0.0.1:6379> hkeys myhash
1) "name"
2) "age"
3) "nane2"
hvals

返回 hash 的所有 value。

127.0.0.1:6379> hvals myhash
1) "Jacob"
2) "24"
3) "Jacob2"
hgetall

獲取某個 hash 中全部的 filed 及 value。

127.0.0.1:6379> hgetall myhash
1) "name"
2) "Jacob"
3) "age"
4) "24"
5) "nane2"
6) "Jacob2"

可見,一下子將 myhash 中所有的 field 及對應的 value 都取出來了。