zoukankan      html  css  js  c++  java
  • 键、值以及通道

    在对待Redis时候,键和其他的事物之间有个相当重要的区别。键是在数据库中一段数据的唯一标识(可能String,List,Hash或者其他的Redis数据类型)。键是没有任何实质意义,就是一个简单的名字。进一步说:当处理集群或者分片系统时,它就是定义在包含数据的节点上的Key,所以对于命令传送来说key是至关重要的。

    值是相对于键来存储的。要么是单个(String数据)要么一组组的。值不会影响命令的传送(注意:除了SORT命令,并且该命令与BY或者GET组合使用的时候,但是这个真的很难解释说明;详细可以去看Redis的SORT命令文档)。值通常会被Redis以操作为目的来解读:

    • inc (各种类似的命令)解读字符串值作为数字数据

    • 排序:值要么以数值或以Unicode规则来排序

    • 还有很多其他的

    关键点在于API需要明白什么是Key和什么是Value。这个涉及到StackExchange.Redis的API,但是大多数时候你根本不需要知道这个。

    当你在使用发布/订阅时,我们是使用通道来处理的;通道不影响到命令传送(所以它们不是Keys),但是这与常规值是区别巨大的,所以应该分别考虑。

    Keys

    StackExchange.Redis中键的类型是 RedisKey。不过好在它会隐式的从 string 和 byte[] 转换,允许使用文本和二进制键。例如:StringIncrement 方法将 RedisKey 作为第一个参数,但是你不需要自己去做转换,例如:

    string key = ...
    db.StringIncrement(key);

    或者

    byte[] key = ...
    db.StringIncrement(key);

    同样的,有一些方法能够返回 RedisKey 类型的key;如下所示:

    string someKey = db.KeyRandom();

    Values

    StackExchange.Redis中的值的类型是 RedisValue。与 RedisKey 一样,它也可以隐式转换;这意味着你大多数时候都看不到该类型,例如:

    db.StringSet("mykey", "myvalue");

    然而,除了文本和二进制内容外,值还可以被表示为其他原生类型,如:Int32, Int64, Double, Boolean。正因为如此,RedisValue 提供了大量的隐式转换支持,而 RedisKey 则没有这么多:

    db.StringSet("mykey", 123); // 这仍旧是一个RedisKey 和 RedisValue
    ...
    int i = (int)db.StringGet("mykey");

    注意:从原生类型到 RedisValue 的转换都是隐式的,但是从 RedisValue 转换为原生类型是显示转换:如果数据没有一个适当的值,这些转换很有可能会失败。

    注意:当值是数值类型时,Redis去获取一个不存在(no-existent)的键值时,该值会以数值0返回;为了一致性,nil响应被视作为0:

    db.KeyDelete("abc");
    int i = (int)db.StringGet("abc"); // 这个会被作为0返回

    如果你需要检测nil条件,那么你可以这样做:

    db.KeyDelete("abc");
    var value = db.StringGet("abc");
    bool isNil = value.IsNull; // 这个表示真

    或者这样做更简单,使用 Nullable<T>:

    db.KeyDelete("abc");
    var value = (int?)db.StringGet("abc"); // 正如你所期望的,会返回空

    Hashes

    由于哈希表中的字段名不会影响到命令的传送,他们也不是key,但是文本和二进制可以作为名字使用;因此它们被视作为值。

    Channels

    发布/订阅所使用的管道名字的类型是 RedisChannel;大致上来说和 RedisKey 相同,但是被独立处理的,因为管道名称是头等公民,它们不会影响命令的传输。

    Scripting

    Redis中的Lua脚本有两个值得注意的特性:

    • 输入必须保证键值分离(在脚本内会分别变成 KEYS 和 ARGV)

    • 返回的格式没有被预先定义:这取决于你的脚本

    由于这个原因,ScriptEvaluate 方法接受两个单独的输入数组:一个是作为Key的 RedisKey[],一个是作为Value的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的Key和Value。然而,几乎在所有情况下,你不需要直接引用所涉及的基础类型,默认提供了转换操作。

  • 相关阅读:
    java编译错误No enclosing instance of type TestFrame is accessible. Must qualify the allocation with an enclosing instance of type TestFrame (e.g. x.new A(
    java 2中创建线程方法
    动态规划基本思想
    关于eclipse编译一个工程多个main函数
    java Gui初识
    Eclipse中java项目的打包
    java 播放声音
    把资源文件夹导入到eclipse中
    Java建立JProgressBar
    How to grant permissions to a custom assembly that is referenced in a report in Reporting Services
  • 原文地址:https://www.cnblogs.com/carldai/p/5497034.html
Copyright © 2011-2022 走看看