如何在 .NET 程式中使用 Redis 做為 Cache Server - Part 4 (使用 Sets 型別)

今天來看看 Sets 該怎麼使用,建議可與 如何在 .NET 程式中使用 Redis 做為 Cache Server - Part 3 (使用 Lists 型別) 參照

先說重點:用法與 Lists 幾乎相同,差別是 Sets 的元素不允許重複,如果有興趣多瞭解 StackExchange.Redis 指令對應文中有對應與簡介說明表

基礎建設

  1. 處理 redis 連線 factory

    • 使用 StackExchange.Redis 套件,記得 nuget 安裝

      public static class RedisConnectionFactory
      {
          private static readonly Lazy<ConnectionMultiplexer> Connection;
          static RedisConnectionFactory()
          {
              var connectionString = "localhost:6379";
              var options = ConfigurationOptions.Parse(connectionString);
              Connection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(options));
          }
          public static ConnectionMultiplexer GetConnection => Connection.Value;
          public static IDatabase RedisDB => GetConnection.GetDatabase();
      }
      
  2. 測試用自訂 class

    public class Person
    {
        public string ID{ get; set; }
            
        public string Name { get; set; }
        
        public string Tel { get; set; }
    }
    
  3. 存取 redis 用的 object

    IDatabase _db = RedisConnectionFactory.RedisDB;
    
  4. 製造假資料

    Dictionary<string, List<Person>> peopleDic = new Dictionary<string, List<Person>>();
    for (int i = 0; i < 3; i++)
    {
        var _id = Guid.NewGuid().ToString();
        List<Person> people = new List<UserQuery.Person>();
        for (int j = 0; j < 3; j++)
        {
            people.Add((new Person { ID = $"{i}_{j}_ID", Name = $"{i}_{j}_yowko", Tel = $"{i}_{j}_0123456789" }));
        }
        peopleDic.Add(_id, people);
    }
    
  5. 使用 batch 來批次處理指令

    var batch = _db.CreateBatch();
    

使用 Sets 型別

  • 相關指令介紹

    指令參數對應 StackExchange.Redis 指令說明
    SADDkey member [member …]SetAdd/SetAddAsync添加一個或者多個元素(member) 到 set(key) 裡
    SCARDkeySetLength/SetLengthAsync取得 set(key) 裡面的元素數量
    SDIFFkey [key …]SetCombine/SetCombineAsync取得一個 set(key) 與其他 set(key) 間的差集元素
    SDIFFSTOREdestination key [key …]SetCombineAndStore/SetCombineAndStoreAsync將一個 set(key) 與其他 set 間的差集元素,儲存至 destination
    SINTERkey [key …]SetCombine/SetCombineAsync取得兩個 set 的交集
    SINTERSTOREdestination key [key …]SetCombineAndStore/SetCombineAndStoreAsync將一個 set(key) 與其他 set 間的交集,儲存至 destination
    SISMEMBERkey memberSetContains/SetContainsAsync檢查 member 存在於特定 set(key)
    SMEMBERSkeySetMembers/SetMembersAsync取得 set(key) 裡面的所有元素
    SMOVEsource destination memberSetMove/SetMoveAsync移動 set(source) 裡面的 元素(member) 到另一個 set(destination)
    SPOPkey [count]SetPop/SetPopAsync刪除並取得 set(key) 裡的 count 個元素
    SRANDMEMBERkey [count]SetRandomMember/SetRandomMemberAsync
    SetRandomMembers/SetRandomMembersAsync
    從 set(key) 裡面隨機獲取 count 個元素
    SREMkey member [member …]SetRemove/SetRemoveAsync從 set(key) 裡刪除一個或多個元素(member)
    SUNIONkey [key …]SetCombine/SetCombineAsync傳回多個 set(key) 的聯集的所有元素(member)
    SUNIONSTOREdestination key [key …]SetCombineAndStore/SetCombineAndStoreAsync將多個 set(key) 的聯集的所有元素,儲存至 destination
    SSCANkey cursor [MATCH pattern] [COUNT count]SetScan逐一列出 set(key) 中的元素

實際使用

  • 範例程式碼

    var batch = _db.CreateBatch();
    foreach (var item in peopleDic)
    {
        foreach (var element in item.Value)
        {
            _db.SetAddAsync(item.Key, JsonConvert.SerializeObject(element));
        }
    }
    batch.Execute();
    
  • 儲存狀況

    1result

完整程式碼

void Main()
{
	IDatabase _db = RedisConnectionFactory.RedisDB;
	Dictionary<string, List<Person>> peopleDic = new Dictionary<string, List<Person>>();
	for (int i = 0; i < 3; i++)
	{
		var _id = Guid.NewGuid().ToString();
		List<Person> people = new List<UserQuery.Person>();
		for (int j = 0; j < 3; j++)
		{
			people.Add((new Person { ID = $"{i}_{j}_ID", Name = $"{i}_{j}_yowko", Tel = $"{i}_{j}_0123456789" }));
		}
		peopleDic.Add(_id, people);
	}
	var batch = _db.CreateBatch();
	foreach (var item in peopleDic)
	{
		foreach (var element in item.Value)
		{
			_db.SetAddAsync(item.Key, JsonConvert.SerializeObject(element));
		}
	}
	batch.Execute();
}

public class Person 
{
	public string ID { get; set; }

	public string Name { get; set; }

	public string Tel { get; set; }
}

public static class RedisConnectionFactory
{
	private static readonly Lazy<ConnectionMultiplexer> Connection;
	static RedisConnectionFactory()
	{
		var connectionString = "localhost:6379";
		var options = ConfigurationOptions.Parse(connectionString);
		Connection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(options));
	}
	public static ConnectionMultiplexer GetConnection => Connection.Value;
	public static IDatabase RedisDB => GetConnection.GetDatabase();
}

參考資料

  1. Redis - Sets
  2. GitHub - StackExchange.Redis
  3. redis set 操作(和list區別是裡面存在的元素不重複)