一、简介

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. max10之pll时钟源切换

    问题3:PLL切换功能中,多次切换可能造成PLL锁不定 从现象看clkbadx信号是不影响的,但locked信号一定是有影响的.

  2. DDR中的命令

    (3) 列地址选择(CAS#): 选择器件内感兴趣的地址列 行地址选择(RAS#): 选择设备中感兴趣的地址行. (4)(precharge)预充电 DRAM读取具有破坏性,也就是说,在读操作中会破坏 ...

  3. MySQL 安装与使用(三)

    操作系统:CentOS release 5.10 (Final) MySQL版本:5.1.72-community 占位学习与编辑中……

  4. centos6.4 安装wireless驱动

    安装完centos6.4之后,目测只有有线的驱动,没有无线驱动. 一.检测网卡 [root@centos ~]# lspci | grep Net :.11b/g LP-PHY (rev ) :) 第 ...

  5. Beta阶段第一篇 Scrum 冲刺博客

    介绍小组新加入的成员,Ta担任的角色 新成员 担任角色 张晨晨 测试 理由:晨晨代码能力有待提高,但心思细腻有耐心,适合测试工作. 讨论是否需要更换团队的PM 通过团队讨论决定不更换团队PM,理由是在 ...

  6. Q他中的乱码再理解

    Qt版本有用4的版本的也有用5的版本,并且还有windows与linux跨平台的需求. 经常出现个问题是windows的解决了,源代码放到linux上编译不通过或者中文会乱码,本文主要是得出一个解决方 ...

  7. js-图片时间(倒计时)

    <!DOCTYPE html><html>    <head>        <meta charset="UTF-8">      ...

  8. Shell 命令实现词频统计

    杨贵福老师的方法 cat tr sed sort head 命令的综合使用方式1 $ cat pg11.txt |tr -cs A-Za-z\' '\n' |sed "/'/d"| ...

  9. C# 嵌入dll

    在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形式总归让人不爽,那么有 ...

  10. 利用Knockoutjs对电话号码进行验证

    问题来源 最近在项目中前端使用Knockoutjs,验证模块自然也是使用Knockoutjs来进行表单验证了,比较头痛,因为没有使用过Knockoutjs,更加别说要去用它做表单验证了,于是乎恶补了一 ...