一、简介

Redis中的Hash字典相当于C#中的Hashtable,是一种无序字典,内存存储了很对的键值对,实现上和Hashtable一样,都是"数组+链表"二维结构,都是对关键字(键值)进行散列操作,讲关键字散列到Hashtable中的某一个槽位中去,这个过程中如果发生了碰撞,散列函数可能将不同的关键字散列到Hashtable中的同一个槽位中去,通过"链表的方式"进行连接。

后续可能会写一个分类的关于C#中常用算法的文章,但这里不想介绍太多.

不同的是.Redis中Hash(字典的值)只能是字符串,C#中为Hashtable为object

另外关于Hashtable和List等类型,如果你阅读源码,当它们的实际容量达到初始设置的时候,一般都会创建一个新的对象,list中的原先的两倍,然后将原先的元素复制到新的对象中,这个过程如果里面的元素超级多,那么这个开销非常大,Hashtable也是如此,Hashtable中的这个过程专业术语叫rehash,而Redis为了避免这个开销,采用了"渐近式的"rhash操作,"渐进"式rehash操作会在rehash的同时,保留新旧两个hash结构,查询时会同时查询这两个hash对象,接受在后续的定时任务中循序渐进的将旧hash的内容一点点的迁移到新的hash对象中去.当迁移完成,原先的hash结构会被弃用.对应的内存会被回收.

二、Hash(字典)的用途

hash结构可以用来存储用户信息,当然字符串也可以,但是他和字符串的区别如下:

(1)、如果使用字符串存储,我们需要以用户Id为键,然后将用户所有的信息序列化成字符串存到Redis中,如果用户的信息很多,且如果有些业务我们只需要用户的部分信息,那我们不得不将用户所有的信息取过来,然后反序列化,将业务需要的数据传递过去,这个过程,Redis和客户端的网络请求流量很客观,当然访问量少不需要考虑这些问题,但是如果访问量大的话,你懂的

(2)、如果使用Hash结构存储,那么我们可以用户结构的单个字段进行存储,当我们需要用户信息时,就可以进行部分读取,节省网络流量.

(3)、当然Hash也有缺点,他的存储消耗要高于字符串.

三、实战

centeros7中启动Redis

还是接着前面随笔的代码进行扩展.

C#控制台:

给RedisClient.cs文件扩展如下几个方法:

        /// <summary>
/// 异步可批量设置Hash(字典)
/// </summary>
/// <param name="key"></param>
/// <param name="entries"></param>
/// <returns></returns>
public static async Task HashSetAsync(RedisKey key, HashEntry[] entries)
{
var db = GetDatabase();
await db.HashSetAsync(key, entries);
} /// <summary>
/// 异步根据键获取值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static async Task<RedisValue[]> HashValuesAsync(RedisKey key)
{
var db = GetDatabase();
return await db.HashValuesAsync(key);
} /// <summary>
/// 异步根据键获取键值对
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static async Task<HashEntry[]> HashGetAllAsync(RedisKey key)
{
var db = GetDatabase();
return await db.HashGetAllAsync(key);
} /// <summary>
/// 根据键和和键值对的键获取某个对应的值
/// </summary>
/// <param name="key"></param>
/// <param name="field"></param>
/// <returns></returns>
public static async Task<RedisValue> HashGetAsync(RedisKey key,RedisValue field)
{
var db = GetDatabase();
return await db.HashGetAsync(key, field);
}

注:这里还提供了删除Hash集合和给对应的Filed加1的操作,但是个人觉得应用场景不多,一般都是每天跑后台服务持久化到数据库中对数据库进行操作,比较好,所以这里就没有扩展.

Program.cs代码如下:

    class Program
{
static Program()
{
//链式配置Redis
AppConfiguration.Current.ConfigureRedis<RedisConfig>();
} static void Main(string[] args)
{
StringSetGetAsync();
Console.ReadKey();
} static async void StringSetGetAsync()
{
var key = "测试Hash键";
var age = new KeyValuePair<RedisValue, RedisValue>("Age", );
var name = new KeyValuePair<RedisValue, RedisValue>("Name", "小超");
var sex = new KeyValuePair<RedisValue, RedisValue>("Sex", "男");
try
{
await RedisClient.HashSetAsync(key,new HashEntry[] { age,name, sex });
var entries=await RedisClient.HashGetAllAsync(key);
//根据键获取键值对
foreach (var item in entries)
{
Console.WriteLine($"键:{item.Name},值:{item.Value}");
}
//根据键获取值,如果不需要获取键
Console.WriteLine("只获取值,不获取键的操作");
var values= await RedisClient.HashValuesAsync(key);
foreach (var value in values)
{
Console.WriteLine($"{value}");
} //根据键和和键值对集合的键获取某个对应的值
Console.WriteLine("根据键和和键值对集合的键获取某个对应的值的操作");
var fieldValue = await RedisClient.HashGetAsync(key,"Name");
Console.WriteLine($"获取键为:{key}下的键值对集合中的键为Name的值:{fieldValue}");
}
catch (Exception)
{
//记录日志
Console.WriteLine("Redis,使用异常");
} } class UserInfo
{
internal string Name { get; set; } internal int Age { get; set; }
}
}

Redis学习系列四Hash(字典)的更多相关文章

  1. 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  2. 分布式缓存技术redis学习(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  3. Python操作redis学习系列之(集合)set,redis set详解 (六)

    # -*- coding: utf-8 -*- import redis r = redis.Redis(host=") 1. Sadd 命令将一个或多个成员元素加入到集合中,已经存在于集合 ...

  4. 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)

    本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...

  5. 分布式缓存技术redis学习系列

    分布式缓存技术redis学习系列(一)--redis简介以及linux上的安装以及操作redis问题整理 分布式缓存技术redis学习系列(二)--详细讲解redis数据结构(内存模型)以及常用命令 ...

  6. redis学习系列

    redis学习系列 基本看完 最近在看redis的代码,简单记录下自己认为重要的点,自己写比较费时间的,我会把查到的资料贴出来方便查看 淘宝的redis内存分析 http://www.searchtb ...

  7. C# Redis学习系列三:Redis配置主从

    Redis配置主从 主IP :端口      192.168.0.103 6666 从IP:端口       192.168.0.108 3333 配置从库 (1)安装服务: redis-server ...

  8. scrapy爬虫学习系列四:portia的学习入门

    系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备:      http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...

  9. DocX开源WORD操作组件的学习系列四

    DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...

随机推荐

  1. Java潜在的坑持续总结

    1.Java里如果有if (foo == 0),如果foo是null这里居然是会抛NPE异常而不是返回false: 2.Java里整形数值不能用==来比较,因为只有区间是[-128,127]的才能这么 ...

  2. 调试问题集之——Max10中配置完成后程序不能运行

    CONF_DONE信号是一个双向信号并且是Open-Drain.在配置过程中和配置之前作为输出,且为低电平.配置完成之后CONF_DONE作为输入脚,因为Open-Drain,所以必须由外部拉高,但二 ...

  3. 【王者荣耀之IT大神版】铭文说明

    铭文共分五级: 一级:仅有老师提供的笔记 二级:添加了自己的听课笔记 三级:添加问题+解决方案(常遇到的问题以及自己实践上遇到的问题,排位赛遇到的遗忘点) 四级:熟记铭文与并添加联想学过的知识 五级: ...

  4. 【Javascript第二重境界】序

    JS是个人比较喜欢的一门语言,在前端开发中也处于核心位置.前面断断续续的研究了一段时间,这其中包括 对象,原型,继承,函数,设计模式,模块,DOM操作,以及其它又多又琐碎的知识点,而且大部分内容都没有 ...

  5. Chapter15 Principles of Metabolic Regulation

    15.1 调节代谢的通路 (1)细胞和有机体维持着动态稳定 调节作用的基因多 2500个 12% 激酶占比多 300个 一个通路受到多方调节 (2)酶的数量和催化活性 可以被调节 反应物的调控 糖酵解 ...

  6. (广搜)Fire Game -- FZU -- 2150

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82828#problem/I Fire Game Time Limit:1000MS    ...

  7. noip第34课作业

    1.    信息加密 [问题描述] 在传递信息的过程中,为了加密,有时需要按一定规则将文本转换成密文发送出去.有一种加密规则是这样的:1. 对于字母字符,将其转换成其后的第3个字母.例如:A→D,a→ ...

  8. Redis集群错误

    部署Redis集群时出现如下错误: >>> Creating cluster>>> Performing hash slots allocation on 9 no ...

  9. libgdx游戏中的中文字体工具类

    // ---------全局Font------------ static FreeTypeFontGenerator Generator; static BitmapFont Font; stati ...

  10. XE7 & FMX 那些年我们一起上过的控件:ListView 之 (3) 加载数据时如何显示自定义样式

    本文介绍一下ListView下如何加载数据.及使用进度条反馈当前进度给用户. 注意: 原创作品,请尊重作者劳动成果,转载请注明出处!!!原文永久固定地址:http://www.cnblogs.com/ ...