zoukankan      html  css  js  c++  java
  • Redis分布式缓存系列(四)- Redis中的Set类型

    本系列将和大家分享Redis分布式缓存,本章主要简单介绍下Redis中的Set类型,以及如何使用Redis解决数据去重、共同好友、可能认识、统计访问网站的IP数、统计点赞数和随机获取某项值等问题。

    Set类型:用哈希表来保持字符串的唯一性,没有先后顺序,存储一些集合性的数据。(去重、无序集合

    Set类型最大的特点就是无序、去重,以及交集、差集、并集的使用。

    存储形式:key--List<value>

    首先先给大家Show一波Redis中与Set类型相关的API:

    using System.Collections.Generic;
    
    namespace TianYa.Redis.Service
    {
        /// <summary>
        /// Set:用哈希表来保持字符串的唯一性,没有先后顺序,存储一些集合性的数据。(去重、无序集合、交差并的使用)
        /// 1、共同好友、可能认识(二度好友)
        /// 2、利用唯一性,可以统计访问网站的所有独立IP
        /// </summary>
        public class RedisSetService : RedisBase
        {
            #region 添加
    
            /// <summary>
            /// 往set集合中添加item
            /// </summary>
            public void AddItemToSet(string setId, string item)
            {
                base._redisClient.AddItemToSet(setId, item);
            }
    
            /// <summary>
            /// 往set集合中添加list集合
            /// </summary>
            public void AddRangeToSet(string setId, List<string> items)
            {
                base._redisClient.AddRangeToSet(setId, items);
            }
    
            #endregion 添加
    
            #region 获取
    
            /// <summary>
            /// 随机获取set集合中的一个值
            /// </summary>
            public string GetRandomItemFromSet(string setId)
            {
                return base._redisClient.GetRandomItemFromSet(setId);
            }
    
            /// <summary>
            /// 获取set集合中值的数量
            /// </summary>
            public long GetSetCount(string setId)
            {
                return base._redisClient.GetSetCount(setId);
            }
    
            /// <summary>
            /// 获取set集合中的所有值
            /// </summary>
            public HashSet<string> GetAllItemsFromSet(string setId)
            {
                return base._redisClient.GetAllItemsFromSet(setId);
            }
    
            #endregion 获取
    
            #region 删除
    
            /// <summary>
            /// 随机删除set集合中的一个值
            /// </summary>
            /// <returns>返回删除的值</returns>
            public string RandomRemoveItemFromSet(string setId)
            {
                return base._redisClient.PopItemFromSet(setId);
            }
    
            /// <summary>
            /// 随机删除set集合中的count个值
            /// </summary>
            /// <returns>返回删除的值</returns>
            public List<string> RandomRemoveItemsFromSet(string setId, int count)
            {
                return base._redisClient.PopItemsFromSet(setId, count);
            }
    
            /// <summary>
            /// 删除set集合中指定的item
            /// </summary>
            public void RemoveItemFromSet(string setId, string item)
            {
                base._redisClient.RemoveItemFromSet(setId, item);
            }
    
            #endregion 删除
    
            #region 其它
    
            /// <summary>
            /// 从fromSetId集合中移除值为item的值,并把item添加到toSetId集合中
            /// </summary>
            public void MoveBetweenSets(string fromSetId, string toSetId, string item)
            {
                base._redisClient.MoveBetweenSets(fromSetId, toSetId, item);
            }
    
            /// <summary>
            /// 返回setIds多个集合中的并集
            /// </summary>
            public HashSet<string> GetUnionFromSets(params string[] setIds)
            {
                return base._redisClient.GetUnionFromSets(setIds);
            }
    
            /// <summary>
            /// 返回setIds多个集合中的交集
            /// </summary>
            public HashSet<string> GetIntersectFromSets(params string[] setIds)
            {
                return base._redisClient.GetIntersectFromSets(setIds);
            }
    
            /// <summary>
            /// 返回withSetIds多个集合中的差集
            /// </summary>
            /// <param name="fromSetId">原集合</param>
            /// <param name="withSetIds">其他集合</param>
            /// <returns>出现在原集合,但不包含在其他集合</returns>
            public HashSet<string> GetDifferencesFromSet(string fromSetId, params string[] withSetIds)
            {
                return base._redisClient.GetDifferencesFromSet(fromSetId, withSetIds);
            }
    
            /// <summary>
            /// 将setIds多个集合中的并集放入intoSetId集合中
            /// </summary>
            public void StoreUnionFromSets(string intoSetId, string[] setIds)
            {
                base._redisClient.StoreUnionFromSets(intoSetId, setIds);
            }
    
            /// <summary>
            /// 把fromSetId集合中的数据与withSetIds集合中的数据对比,fromSetId集合中不存在withSetIds集合中,则把这些不存在的数据放入intoSetId集合中
            /// </summary>
            public void StoreDifferencesFromSet(string intoSetId, string fromSetId, string[] withSetIds)
            {
                base._redisClient.StoreDifferencesFromSet(intoSetId, fromSetId, withSetIds);
            }
    
            #endregion 其它
        }
    }

    下面我们就来看下如何使用上面的API来解决一些具体的问题:

    一、数据去重

    其实,统计访问网站的IP数、统计点赞数、投票限制以及添加好友申请等这是同一类型的问题,都是去重问题,而我们的Set类型默认就能够帮我们实现去重。

    /// <summary>
    /// Set:去重、交差并的使用
    /// 去重:IP统计去重;添加好友申请;投票限制;点赞;
    /// </summary>
    public static void ShowSet()
    {
        using (RedisSetService service = new RedisSetService())
        {
            service.FlushAll(); //清理全部数据
    
            //添加后自动去重
            service.AddItemToSet("advanced", "111");
            service.AddItemToSet("advanced", "112");
            service.AddItemToSet("advanced", "114");
            service.AddItemToSet("advanced", "114");
            service.AddItemToSet("advanced", "115");
            service.AddItemToSet("advanced", "115");
            service.AddItemToSet("advanced", "113");
    
            var result = service.GetAllItemsFromSet("advanced"); //获取去重后所有的项
            var count = service.GetSetCount("advanced"); //独立的ip数
            var random = service.GetRandomItemFromSet("advanced"); //随机获取某一项值
    
            Console.WriteLine($"result:{JsonConvert.SerializeObject(result)}");
            Console.WriteLine($"count:{count}");
            Console.WriteLine($"random:{random}");
        }
    }

    运行结果如下所示:

    从运行结果可以看出,往Set集合里面添加数据的时候会自动去重。另外还可以使用GetRandomItemFromSet方法随机获取Set集合中的某一项值

    二、交集、差集和并集的使用

    using System;
    using TianYa.Redis.Service;
    using Newtonsoft.Json;
    
    namespace MyRedis.Scene
    {
        /// <summary>
        /// Set类型
        /// 好友管理:共同好友,可能认识(二次好友)
        /// </summary>
        public class FriendManager
        {
            /// <summary>
            /// Set类型:交集、差集、并集的使用
            /// 去重:IP统计去重;添加好友申请;投票限制;点赞;
            /// </summary>
            public static void Show()
            {
                using (RedisSetService service = new RedisSetService())
                {
                    service.FlushAll(); //清理全部数据
    
                    //Set1--模拟TianYa的好友
                    service.AddItemToSet("TianYa", "Jack");
                    service.AddItemToSet("TianYa", "Mark");
                    service.AddItemToSet("TianYa", "James");
                    service.AddItemToSet("TianYa", "James");
                    service.AddItemToSet("TianYa", "James");
                    service.AddItemToSet("TianYa", "Bill");
                    service.AddItemToSet("TianYa", "Linda");
    
                    //Set2--模拟Jack的好友
                    service.AddItemToSet("Jack", "TianYa");
                    service.AddItemToSet("Jack", "Mark");
                    service.AddItemToSet("Jack", "Bill");
                    service.AddItemToSet("Jack", "Brooke");
                    service.AddItemToSet("Jack", "John");
    
                    var result1 = service.GetIntersectFromSets("TianYa", "Jack"); //交集(共同好友)
                    var result2 = service.GetDifferencesFromSet("Jack", "TianYa"); //差集(可能认识)
                    var result3 = service.GetDifferencesFromSet("TianYa", "Jack"); //差集
                    var result4 = service.GetUnionFromSets("TianYa", "Jack"); //并集
    
                    Console.WriteLine($"result1={JsonConvert.SerializeObject(result1)}");
                    Console.WriteLine($"result2={JsonConvert.SerializeObject(result2)}");
                    Console.WriteLine($"result3={JsonConvert.SerializeObject(result3)}");
                    Console.WriteLine($"result4={JsonConvert.SerializeObject(result4)}");
                }
            }
        }
    }

    运行结果如下所示:

    至此本文就全部介绍完了,如果觉得对您有所启发请记得点个赞哦!!!

    Demo源码:

    链接:https://pan.baidu.com/s/1B_XUM4Eqc81CJdjufOWS9A 
    提取码:a78n

    此文由博主精心撰写转载请保留此原文链接:https://www.cnblogs.com/xyh9039/p/13996900.html

    版权声明:如有雷同纯属巧合,如有侵权请及时联系本人修改,谢谢!!!

  • 相关阅读:
    devise 异步发邮件
    ubuntutweak for lucid
    960gs blueprint
    Amoeba for mysql 0.31发布(读写分离、负载均衡、Failover、数据切分)
    Google App Servlet容器转型 – 从Tomcat到Jetty
    DBeaver
    用simple from暂不用formtastic
    [SQL Server]ORDER BY的问题
    PHP pathinfo() 函数
    php中使用head进行二进制流输出,让用户下载PDF等附件的方法
  • 原文地址:https://www.cnblogs.com/xyh9039/p/13996900.html
Copyright © 2011-2022 走看看