设为首页 收藏本站
查看: 985|回复: 0

[经验分享] StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用

[复制链接]

尚未签到

发表于 2017-12-21 10:41:26 | 显示全部楼层 |阅读模式
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>{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();
  }
  

DSC0000.png


SortedSet


  • 特点:有序排列,值不可重复。类似Set,不同的是sortedset的每个元素都会关联一个double类型的score,用此元素来进行排序
  • 需求:显示文章被赞最多的十条评论
  • 实现:
  

public void HotestUserTop10()  {
  IDatabase db
= StackExchangeRedisHelper.GetDatabase();//模拟有一百名评论者,开始每个用户被“赞”的次数为1  List<SortedSetEntry> entrys = new List<SortedSetEntry>();
  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+":"+ db.SortedSetScore("文章1", userStores));
  }
  db.KeyDelete("文章1");
  Console.ReadLine();
  }
  

DSC0001.png


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();
  }
  

DSC0002.png

  以下代码是我分别用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();
  }
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-426381-1-1.html 上篇帖子: Spring整合Redis(spring-data 下篇帖子: Redis发布订阅使用方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表