1.简介
Redis 的 Set 是 string 类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
集合中最大的成员数为 232- 1(4294967295, 每个集合可存储40多亿个成员)。
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
2.使用场景
集合主要应用在一些需要求交集、并集、补集这样的场景,比如我们需要求共同好友、共同兴趣爱好、共同关注的微博,限制同一个账号多处登录系统等场景。
3.set数据结构示意图
set类型在存储数据时,是以key-List<value>格式存储的,如下图所示:
例如,一个用户tom,他的兴趣有编程,音乐,运动,就可以用set表示:
如下是对set封装后的api方法,RedisSetService.cs,代码如下:
using MyRedis.Redis.Interface;
using System.Collections.Generic;
namespace MyRedis.Redis.Service
{
public class RedisSetService : RedisBase
{
#region 添加
/// <summary>
/// key集合中添加value
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void AddItemToSet(string key, string value)
{
base.iClient.AddItemToSet(key, value);
}
/// <summary>
/// key集合中添加list集合
/// </summary>
/// <param name="key"></param>
/// <param name="list"></param>
public void AddRangeToSet(string key, List<string> list)
{
base.iClient.AddRangeToSet(key, list);
}
#endregion
#region 获取
/// <summary>
/// 随机获取key集合中的一个值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string GetRandomItemFromSet(string key)
{
return base.iClient.GetRandomItemFromSet(key);
}
/// <summary>
/// 获取key集合值的数量
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public long GetSetCount(string key)
{
return base.iClient.GetSetCount(key);
}
/// <summary>
/// 获取所有key集合的值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public HashSet<string> GetAllItemsFromSet(string key)
{
return base.iClient.GetAllItemsFromSet(key);
}
#endregion
#region 删除
/// <summary>
/// 随机删除key集合中的一个值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string PopItemFromSet(string key)
{
return base.iClient.PopItemFromSet(key);
}
/// <summary>
/// 删除key集合中的value
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public void RemoveItemFromSet(string key, string value)
{
base.iClient.RemoveItemFromSet(key, value);
}
#endregion
#region 其它
/// <summary>
/// 从fromkey集合中移除值为value的值,并把value添加到tokey集合中
/// </summary>
/// <param name="fromkey"></param>
/// <param name="tokey"></param>
/// <param name="value"></param>
public void MoveBetweenSets(string fromkey, string tokey, string value)
{
base.iClient.MoveBetweenSets(fromkey, tokey, value);
}
/// <summary>
/// 返回keys多个集合中的并集
/// </summary>
/// <param name="keys"></param>
/// <returns></returns>
public HashSet<string> GetUnionFromSets(params string[] keys)
{
return base.iClient.GetUnionFromSets(keys);
}
/// <summary>
/// 返回keys多个集合中的交集
/// </summary>
/// <param name="keys"></param>
/// <returns></returns>
public HashSet<string> GetIntersectFromSets(params string[] keys)
{
return base.iClient.GetIntersectFromSets(keys);
}
/// <summary>
/// 返回keys多个集合中的差集
/// </summary>
/// <param name="fromKey">原集合</param>
/// <param name="keys">其它集合</param>
/// <returns>出现在原集合,但不包括在其他集合</returns>
public HashSet<string> GetDifferencesFromSet(string fromKey, params string[] keys)
{
return base.iClient.GetDifferencesFromSet(fromKey, keys);
}
/// <summary>
/// keys多个集合中的并集,放入newkey集合中
/// </summary>
/// <param name="newkey"></param>
/// <param name="keys"></param>
public void StoreUnionFromSets(string newkey, string[] keys)
{
base.iClient.StoreUnionFromSets(newkey, keys);
}
/// <summary>
/// 把fromkey集合中的数据与keys集合中的数据进行比对,fromkey集合中不存在keys集合中,则把这些不存在的数据放入newkey
/// </summary>
/// <param name="newkey"></param>
/// <param name="fromkey"></param>
/// <param name="keys"></param>
public void StoreDifferencesFromSet(string newkey, string fromkey, string[] keys)
{
base.iClient.StoreDifferencesFromSet(newkey, fromkey, keys);
}
#endregion
}
}
上面的代码创建完成后,项目的基础就构建完成了,下面开始学习set数据类型常用api的使用。
在控制台应用程序中的ServiceStackTest.cs类中,调用Redis的api方法。代码如下:
using MyRedis.Redis.Service;
using System;
using System.Collections.Generic;
using System.Threading;
namespace MyRedis
{
/// <summary>
/// ServiceStackTest api 封装测试
/// </summary>
public class ServiceStackTest
{
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Remark { get; set; }
public int Age { get; set; }
}
public static void Show()
{
#region RedisSetService
using (RedisSetService setService = new RedisSetService())
{
setService.FlushAll();
//模拟zhangsan和lisi的好友列表
setService.AddItemToSet("zhangsan", "lisi");
setService.AddItemToSet("zhangsan", "jack");
setService.AddItemToSet("zhangsan", "jam");
setService.AddItemToSet("zhangsan", "alis");
setService.AddItemToSet("zhangsan", "wangwu");
setService.AddItemToSet("lisi", "zhangsan");
setService.AddItemToSet("lisi", "lucy");
setService.AddItemToSet("lisi", "wangwu");
var res1 = setService.GetIntersectFromSets("zhangsan", "lisi");//交集
var res2 = setService.GetDifferencesFromSet("zhangsan", "lisi");//差集 前者有,后者没有的
var res3 = setService.GetUnionFromSets("zhangsan", "lisi");//并集 两者所有的合起来
Console.WriteLine("************** 交集 ******************");
foreach (var item in res1)
{
Console.WriteLine(item);
}
Console.WriteLine("************** 差集 ******************");
foreach (var item in res2)
{
Console.WriteLine(item);
}
Console.WriteLine("************** 并集 ******************");
foreach (var item in res3)
{
Console.WriteLine(item);
}
}
#endregion
}
}
}
执行结果:
执行后可以从可视化工具看到Redis中存储的数据信息:
通过上文,我们可以知道集合的主要几个特性,无序、不可重复、支持并交差等操作。因此集合类型比较适合用来数据去重和保障数据的唯一性,还可以用来统计多个集合的交集、错集和并集等,当我们存储的数据是无序并且需要去重的情况下,比较适合使用集合类型进行存储。
更多hash的用法,参考文章:https://www.cnblogs.com/hunternet/p/12695738.html