【譯】StackExchange.Redis 中文文件(四)鍵、值和頻道
Keys, Values and Channels
在 redis,keys 與其他有很大的區別。key 是資料庫中資料的唯一標識(可以是 String,List,Hash 或任何其他 redis 資料型別)。此外,在處理叢集或分片系統時,關鍵是定義包含此資料的節點(如果有副本,則為節點),因此,這些 key 對於路由命令至關重要。
與 values 形成對比。value 是針對 key 儲存的東西:單獨(針對 String 資料)或成組儲存。value 不影響命令路由(注意:當指定 BY 或 GET 時,SORT 命令除外)。同樣,出於操作目的,value 通常由 redis 解釋:
- incr 命令把 string 當作 numeric
- 排序支援數字或 unicode 規則。
- 更多
關鍵是 API 需要了解什麼是 key 和什麼是 value。這反映在 StackExchange.Redis API 中,但好訊息是,大多數時候你根本不需要了解這一點。
使用 pub/sub 時,我們正在處理 channels;channels 不影響路由(因此它們不是鍵),但是與常規 values 完全不同,因此應單獨考慮。
Keys
StackExchange.Redis 通過 RedisKey
型別表示 keys。它可以與 string
或 byte[]
進行隱式轉換,從而允許使用文字 key 和二進位制 key 而不會造成任何複雜性。 例如,StringIncrement
RedisKey
作為第一個引數:
string key = ...
db.StringIncrement(key);
或者
byte[] key = ...
db.StringIncrement(key);
同樣,有些操作會將 keys 作為 RedisKey
返回:
string someKey = db.KeyRandom();
Values
StackExchange.Redis 通過 RedisValue
型別表示 values。與 RedisKey
一樣,存在隱式轉換,例如:
db.StringSet("mykey", "myvalue");
但是,除了文字和二進位制內容外,value 還可能需要表示型別化的原始資料:最常見的(以.NET術語)Int32
Int64
,Double
或 Boolean
。 因此,與 RedisKey
相比,RedisValue
提供了更多的轉換支援:
db.StringSet("mykey", 123); // this is still a RedisKey and RedisValue
...
int i = (int)db.StringGet("mykey");
請注意,雖然從 value 到 RedisValue
的轉換是隱式的,但從 RedisValue
到 value 的許多轉換都是顯式的:這是因為如果資料沒有適當的值,這些轉換很可能會失敗。
另外需要注意的是,在進行數字處理時,redis 將不存在的 key 視為零; 為了與此保持一致,將 nil 響應視為 0:
db.KeyDelete("abc");
int i = (int)db.StringGet("abc"); // this is ZERO
如果您需要檢測nil條件,則可以進行檢查:
db.KeyDelete("abc");
var value = db.StringGet("abc");
bool isNil = value.IsNull; // this is true
或更簡單地說,只需使用提供的 Nullable<T>
支援:
db.KeyDelete("abc");
var value = (int?)db.StringGet("abc"); // behaves as you would expect
Hashes
由於 hashes 中的欄位名稱不會影響命令路由,因此它們不是 keys,而是可以同時使用文字名稱和二進位制名稱。 因此,就 API 而言,它們被視為 values。
Channels
釋出/訂閱的 channel 名稱由 RedisChannel
型別表示; 這在很大程度上與 RedisKey
相同,但是是獨立處理的,因為儘管 channel name 是一級元素,但它們不會影響命令路由。
Scripting
Redis中的Lua指令碼具有兩個顯著特徵:
- 輸入必須將 keys 和 values 分開(指令碼內的鍵和值分別為 KEYS 和 ARGV)
- 返回格式沒有預先定義:取決於你的指令碼
因此,ScriptEvaluate
方法接受兩個單獨的輸入陣列:一個用於 keys 的 RedisKey[]
,一個用於 values 的 RedisValue[]
(兩者都是可選的,並且如果省略則假定為空)。這可能是你實際上需要在程式碼中輸入 RedisKey
或 RedisValue
的少數幾次之一,這僅僅是由於陣列差異規則所致:
var result = db.ScriptEvaluate(TransferScript,
new RedisKey[] { from, to }, new RedisValue[] { quantity });
(其中 TransferScript
是一些包含Lua的字串,此示例未顯示)
響應使用 RedisResult
型別(這是指令碼編寫所獨有的;通常,API 會嘗試儘可能直接和清晰地表示響應)。和以前一樣,RedisResult
提供了一系列轉換操作:實際上比 RedisValue
更多,因為除了被解釋為文字,二進位制,基元和可為空的基元之外,響應還可以解釋為此類的陣列,例如:
string[] items = db.ScriptEvaluate(...);
總結
在 API 中使用的型別經過精心選擇,以區分 redis keys 和 values。在大多數情況下,提供自動轉換操作。