StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用

Easter79
• 阅读 469

原文: StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用

ConnectionMultiplexer

ConnectionMultiplexer 是StackExchange.Redis的核心对象,用这个类的实例来进行Redis的一系列操作,对于一个整个应用程序应该只有一个ConnectionMultiplexer 类的实例。上一章中StackExchangeRedisHelper 的相关代码如下

private static ConnectionMultiplexer _instance = null;
        /// <summary>
        /// 使用一个静态属性来返回已连接的实例,如下列中所示。这样,一旦 ConnectionMultiplexer 断开连接,便可以初始化新的连接实例。
        /// </summary>
        public static ConnectionMultiplexer Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_locker)
                    {
                        if (_instance == null || !_instance.IsConnected)
                        {
                            _instance = ConnectionMultiplexer.Connect(Coonstr);
                        }
                    }
                }
                //注册如下事件
                _instance.ConnectionFailed += MuxerConnectionFailed;
                _instance.ConnectionRestored += MuxerConnectionRestored;
                _instance.ErrorMessage += MuxerErrorMessage;
                _instance.ConfigurationChanged += MuxerConfigurationChanged;
                _instance.HashSlotMoved += MuxerHashSlotMoved;
                _instance.InternalError += MuxerInternalError;
                return _instance;
            }
        }

 String

 string类型应该是最长用到的了,用法也很简单,下面展示了用Redis来进行基本的字符串数字存储

public static IDatabase GetDatabase()
        {
            return Instance.GetDatabase();
        }
        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void Set(string key, object value, TimeSpan? expiry = default(TimeSpan?), When when = When.Always, CommandFlags flags = CommandFlags.None)
        {
            key = MergeKey(key);
            GetDatabase().StringSet(key, Serialize(value), expiry, when, flags);
        }    
        /// <summary>
        /// 根据key获取缓存对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T Get<T>(string key)
        {
            key = MergeKey(key);
            return Deserialize<T>(GetDatabase().StringGet(key));
        }    
         /// <summary>
        /// 移除指定key的缓存
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool Remove(string key)
        {
            key = MergeKey(key);
            return GetDatabase().KeyDelete(key);
        }    

 除了基本的string类型操作,Redis同时支持以下几种类型的操作

  • List  列表
  • Set  无序集合
  • SortedSet  有序集合
  • Hash 哈希表

下面我依次来介绍下这四种类型在StackExchange.Redis中的基本用法

关于代码中的KeyDelete为删除对应的键,我这里是因为测试防止重复才加上的。大家不要误会

List

  • 特点:有序排列,值可以重复。我们可以通过pop,push操作来从头部和尾部删除或者添加元素。这使得list既可以做栈也可以做队列

  • 需求:要求一条微博将最新的10条评论用户名字直接显示在主页上

  • 实现:

    public static void LatestUserTop10() { IDatabase db = StackExchangeRedisHelper.GetDatabase(); //模拟有一百名用户 for (int i = 1; i <= 100; i++)
    { db.ListLeftPush("user", "用户"+i); //每一名用户插入后都只保留最后的十个用户到redis数据库中 db.ListTrim("user", 0, 9); } RedisValue[] userStores = db.ListRange("user"); foreach (var item in userStores) { Console.Write((string)item + ","); } db.KeyDelete("user"); Console.ReadLine(); }

 Set

  • 特点:无序排列,值不可重复。增加删除查询都很快。提供了取并集交集差集等一些有用的操作

  • 需求:取两篇文章的评论者的交集并集差集

  • 实现:

    public void RedisSetTest() { IDatabase db = StackExchangeRedisHelper.GetDatabase(); for (int i = 1; i <= 20; i++) { db.SetAdd("文章1", i); } for (int i = 15; i <= 35; i++) { db.SetAdd("文章2", i); } RedisValue[] inter = db.SetCombine(SetOperation.Intersect, "文章1", "文章2"); RedisValue[] union = db.SetCombine(SetOperation.Union, "文章1", "文章2"); RedisValue[] dif1 = db.SetCombine(SetOperation.Difference, "文章1", "文章2"); RedisValue[] dif2 = db.SetCombine(SetOperation.Difference, "文章2", "文章1"); int x = 0; Console.WriteLine("两篇文章都评论过的用户"); foreach (var item in inter.OrderBy(m => m).ToList()) { Console.Write((string)item + " "); } Console.WriteLine("\n评论过两篇文章中任意一篇文章的用户"); foreach (var item in union.OrderBy(m => m).ToList()) { Console.Write((string)item + " "); } Console.WriteLine("\n只评论过其第一篇文章的用户"); foreach (var item in dif1.OrderBy(m => m).ToList()) { Console.Write((string)item + " "); } Console.WriteLine("\n只评论过其第二篇文章的用户"); foreach (var item in dif2.OrderBy(m => m).ToList()) { Console.Write((string)item + " "); } db.KeyDelete("文章1"); db.KeyDelete("文章2"); Console.ReadLine(); }

StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用

SortedSet

  • 特点:有序排列,值不可重复。类似Set,不同的是sortedset的每个元素都会关联一个double类型的score,用此元素来进行排序

  • 需求:显示文章被赞最多的十条评论

  • 实现:

    public void HotestUserTop10() { IDatabase db = StackExchangeRedisHelper.GetDatabase(); //模拟有一百名评论者,开始每个用户被“赞”的次数为1 List entrys = new List(); for (int i = 1; i <= 100; i++) { db.SortedSetAdd("文章1", "评论者" + i, 1); } //评论者2又被赞了两次 db.SortedSetIncrement("文章1", "评论者2", 2); //对应的值的score+2 //评论者101被赞了4次 db.SortedSetIncrement("文章1", "评论者101", 4); //若不存在该值,则插入一个新的 RedisValue[] userStores = db.SortedSetRangeByRank("文章1", 0, 10, Order.Descending); for (int i = 0; i < userStores.Length; i++) { Console.WriteLine(userStores[i]+":"+ db.SortedSetScore("文章1", userStores[i])); } db.KeyDelete("文章1"); Console.ReadLine(); }

StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用

Hash

  • 特点:Hash是一个string类型的field和value的对应表,它更适合来存储对象,相比于每个属性进行一次缓存,利用hash来存储整个对象会占用更小的内存。但是存储速度并不会更快

  • 需求:存储一个学生的基本信息

  • 实现:

    public void RedisHashTest() { IDatabase db = StackExchangeRedisHelper.GetDatabase(); db.HashSet("student1", "name", "张三"); db.HashSet("student1", "age", 12); db.HashSet("student1", "class", "五年级"); Console.WriteLine(db.HashGet("student1", "name")); RedisValue[] result = db.HashGet("student1", new RedisValue[] { "name", "age","class" }); Console.WriteLine(string.Join(",",result)); db.KeyDelete("student1"); Console.ReadLine(); }

 StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用

 以下代码是我分别用stringset和hash来存储对象进行的时间及内存比较,内存可通过redis的info命令来查看。

最终显示耗时方面stringset稍微快一点点,内存占用stringset却是hash的二倍

public void RedisHashVsStringSet()
        {
            IDatabase db = StackExchangeRedisHelper.GetDatabase();
            Stopwatch sw = new Stopwatch();
            sw.Start();
            //for (int i = 0; i < 100000; i++)
            //{
            //    db.HashSet("studenths" + i, "name", "张三" + i);
            //    db.HashSet("studenths" + i, "age", 12 + i);
            //    db.HashSet("studenths" + i, "class", "五年级" + i);
            //}
            //Console.WriteLine(sw.Elapsed.TotalMilliseconds);
            //sw.Restart();
            for (int i = 0; i < 100000; i++)
            {
                db.StringSet("studentstr_name" + i, "张三" + i);
                db.StringSet("studentstr_age" + i, 12 + i);
                db.StringSet("studentstr_class" + i, "五年级" + i);
            }
            Console.WriteLine(sw.Elapsed.TotalMilliseconds);
            //for (int i = 0; i < 100000; i++)
            //{
            //    db.KeyDelete("studenths" + i);
            //    db.KeyDelete("studentstr_name" + i);
            //    db.KeyDelete("studentstr_age" + i);
            //    db.KeyDelete("studentstr_class" + i);
            //}
            Console.ReadLine();
        }
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k