一、简介

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. hadoop Mapreduce组件介绍

    MapReduce原理 MapRedcue采用‘分而治之’的思想,对大规模数据集的操作,分发给一个主节点下的各个分节点共同完成,然后通过整合各个节点的中间结果,得到最终结果.Mapreduce就是任务 ...

  2. char类型

    1.JAVA中,char占2字节,16位.可在存放汉字 2.char赋值 char a='a';  //任意单个字符,加单引号. char a='中';//任意单个中文字,加单引号. char a=1 ...

  3. mac终端的命令都失效的解决方法

    step1. 在terminal里面输入: export PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin&qu ...

  4. centos网络配置(手动设置,自动获取)的2种方法3

    不知道为什么最近一段时间网络特别的慢,还老是断,断的时候,局域网都连不上,当我手动设置一下ip后就可以了,搞得我很无语.下面是2种设置网络连接的方法,在说怎么设置前,一定要做好备份工作,特别是对于新手 ...

  5. POJ3280--Cheapest Palindrome(动态规划)

    Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate ...

  6. 使用freemarker导出word

    最近需要将jsp部分页面导出为word文件,环境是Spring+SpringMVC+Hibernate. 我使用的是FreeMarker模板引擎来完成.这是FreeMarker的中文参考手册,感兴趣的 ...

  7. POJ3176 Cow Bowling 2017-06-29 14:33 23人阅读 评论(0) 收藏

    Cow Bowling Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19173   Accepted: 12734 Des ...

  8. Mahout简介

    Mahout简介 一.mahout是什么 Apache Mahout是ApacheSoftware Foundation (ASF)旗下的一个开源项目,提供了一些经典的机器学习的算法,皆在帮助开发人员 ...

  9. npm 及安装

    一.npm nodejs使开发者摆脱了浏览器的束缚,一系列基于nodejs的应用和工具不断出现,无论是在node应用的开发,还是使用中,包管理都扮演着一个很重要的作用.NPM(node package ...

  10. Delphi中break,exit,abort跳出循环的比较

    http://www.delphitop.com/html/hanshu/104.html Delphi中break,exit,abort跳出循环的比较 exit: 退出函数体abort: 遇到异常, ...