鍵,值和通道
在處理redis時,是鍵不是鍵之間有很重要的區(qū)別。
鍵是數(shù)據(jù)庫中數(shù)據(jù)片段(可以是String,List,Hash或任何其他redis數(shù)據(jù)類型)的獨一無二的名稱。
鍵永遠(yuǎn)不會被解釋為...好吧,任何東西:它們只是惰性名稱。
此外,當(dāng)處理集群或分片系統(tǒng)時,它是定義包含此數(shù)據(jù)的節(jié)點(或者如果有從節(jié)點的節(jié)點)的關(guān)鍵 - 因此鍵對于路由命令是至關(guān)重要的。
這與 值 形成對比; 值是單獨(對于字符串?dāng)?shù)據(jù))或分組對鍵的內(nèi)容存儲 。
值不影響命令路由 <small>(注意:使用 SORT 命令時除非指定 BY 或者 GET,否則是很難解釋的)</small>
同樣,為了操作的目的,值通常被redis翻譯為:
-
incr(和各種類似的命令)將String值轉(zhuǎn)換為數(shù)值數(shù)據(jù) - 排序可以使用數(shù)字或unicode規(guī)則解釋值
- 和許多其他操作
關(guān)鍵是使用API需要理解什么是鍵,什么是值。
這反映在StackExchange.Redis API中,但是好消息是,大部分時間你根本不需要知道這一點。
當(dāng)使用 發(fā)布/訂閱 時,我們處理 channels ; channel 不會影響路由(因此它們不是密鑰),但與常規(guī)值非常不同,因此要單考慮。
鍵
StackExchange.Redis 通過 RedisKey 類型表示鍵。
好消息是,可以從 string 和 byte[] 的隱式轉(zhuǎn)換,允許使用文本和二進(jìn)制密鑰,沒有任何復(fù)雜性。
例如,StringIncrement 方法使用一個 RedisKey 作為第一個參數(shù),但是你不需要知道 ;
舉個例子:
string key = ...
db.StringIncrement(key);
or
byte[] key = ...
db.StringIncrement(key);
同樣,有一些操作返回 鍵為 RedisKey - 再次,它依然可以自動隱式轉(zhuǎn)換:
string someKey = db.KeyRandom();
值
StackExchange.Redis 用 RedisValue 類型表示值。 與 RedisKey 一樣,存在隱式轉(zhuǎn)換,這意味著大多數(shù)時候你從來沒有看到這種類型,例如:
db.StringSet("mykey", "myvalue");
然而,除了文本和二進(jìn)制內(nèi)容,值還可能需要表示類型化的原始數(shù)據(jù) - 最常見的(在.NET術(shù)語中)Int32,Int64,Double或Boolean。 因此,RedisValue提供了比 RedisKey 更多的轉(zhuǎn)換支持:
db.StringSet("mykey", 123); // this is still a RedisKey and RedisValue
...
int i = (int)db.StringGet("mykey");
請注意,雖然從基元類型到 RedisValue 的轉(zhuǎn)換是隱式的,但是從 RedisValue 到基元類型的許多轉(zhuǎn)換是顯式的:這是因為如果數(shù)據(jù)沒有合適的值,這些轉(zhuǎn)換很可能會失敗。
另外注意,當(dāng)做數(shù)字 處理時,redis將不存在的鍵視為零; 為了與此一致,將空響應(yīng)視為零:
db.KeyDelete("abc");
int i = (int)db.StringGet("abc"); // this is ZERO
如果您需要檢測空狀態(tài),那么你就可以這樣檢查:
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
哈希
由于哈希中的字段名稱不影響命令路由,它們不是鍵,但可以接受文本和二進(jìn)制名稱, 因此它們被視為用于API目的的值。
通道
發(fā)布/訂閱 的通道名稱由 RedisChannel 類型表示; 這與 RedisKey 大體相同,但是是獨立處理的,因為雖然通道名是正當(dāng)?shù)牡谝活愒?,但它們不影響命令路由?/p>
腳本
redis中的腳本 有兩項顯著的特性:
- 輸入必須保持鍵和值分離(在腳本內(nèi)部分別成為
KEYS和ARGV) - 返回格式未預(yù)先定義:這將特定于您的腳本
正因為如此,ScriptEvaluate 方法接受兩個獨立的輸入數(shù)組:一個用于鍵的 RedisKey [],一個用于值的 RedisValue [] (兩者都是可選的,如果省略則假定為空)。 這可能是你實際需要在代碼中鍵入 RedisKey 或 RedisValue 的少數(shù)幾次之一,這只是因為數(shù)組變動規(guī)則:
var result = db.ScriptEvaluate(TransferScript,
new RedisKey[] { from, to }, new RedisValue[] { quantity });
(其中 TransferScript 是一些包含Lua的 string,在這個例子中沒有顯示)
響應(yīng)使用 RedisResult 類型(這是腳本專用的;通常API嘗試盡可能直接清晰地表示響應(yīng))。 和前面一樣, RedisResult 提供了一系列轉(zhuǎn)換操作 - 實際上比 RedisValue 更多,因為除了可以轉(zhuǎn)換為文本,二進(jìn)制,一些基元類型和可空元素,響應(yīng)也可以轉(zhuǎn)換為 數(shù)組 ,例如:
string[] items = db.ScriptEvaluate(...);
結(jié)論
API中使用的類型是非常故意選擇的,以區(qū)分redis keys 和 values。 然而,在幾乎所有情況下,您不需要直接去參考所涉及的底層類型,因為提供了轉(zhuǎn)換操作。
查看原文
More
作者水平有限,若有疏漏或錯誤還望提醒,十分感謝。
您可以在這里 提出問題 。