☕ NEW! 完成新手任務即可參加抽獎!LINE 星巴克禮券等你拿,名額有限!        🎉 推廣活動:邀請好友註冊 DevLearn,累積推薦抽 LINE 星巴克禮券! 活動詳情 →        🔥 活動期間 2026/4/1 - 5/31 |已有 0 人參加       
redis 初學

📦 Redis 資料型態:String、List、Hash、Set、Sorted Set

📌 五大資料型態總覽

Redis 不只是簡單的 Key-Value 存儲,它支援 五種核心資料型態

型態 說明 常見用途
String 字串(最基本) 快取、計數器、Session
List 有序列表 訊息佇列、最新動態
Hash 雜湊表(欄位-值) 物件儲存、使用者資料
Set 無序集合(不重複) 標籤、共同好友
Sorted Set 有序集合(帶分數) 排行榜、延遲佇列

📌 String:最基本的鍵值對

# 基本操作
SET name "DevLearn"
GET name          # "DevLearn"

# 設定過期時間(秒)
SET token "abc123" EX 3600

# 數值操作
SET counter 0
INCR counter      # 1
INCR counter      # 2
DECR counter      # 1
INCRBY counter 10 # 11

# 批量操作
MSET key1 "val1" key2 "val2"
MGET key1 key2

.NET 程式碼範例

using StackExchange.Redis;

var redis = ConnectionMultiplexer.Connect("localhost:6379");
var db = redis.GetDatabase();

// 字串操作
await db.StringSetAsync("name", "DevLearn");
string name = await db.StringGetAsync("name");

// 帶過期時間
await db.StringSetAsync("token", "abc123", TimeSpan.FromHours(1));

// 計數器
await db.StringSetAsync("views", 0);
long newViews = await db.StringIncrementAsync("views");     // 1
long decreased = await db.StringDecrementAsync("views");     // 0
long addTen = await db.StringIncrementAsync("views", 10);   // 10

📌 List:有序列表

# 從左邊推入
LPUSH tasks "task3" "task2" "task1"

# 從右邊推入
RPUSH tasks "task4"

# 取得範圍(0-based,-1 代表最後一個)
LRANGE tasks 0 -1
# 1) "task1"  2) "task2"  3) "task3"  4) "task4"

# 從左邊彈出
LPOP tasks   # "task1"

# 列表長度
LLEN tasks   # 3

.NET 程式碼範例

// List 操作
await db.ListLeftPushAsync("notifications", "新訂單 #1001");
await db.ListLeftPushAsync("notifications", "新訂單 #1002");

// 取得最新 10 筆通知
RedisValue[] recent = await db.ListRangeAsync("notifications", 0, 9);
foreach (var item in recent)
    Console.WriteLine(item);  // 新訂單 #1002, 新訂單 #1001

// 彈出(當作佇列使用)
string next = await db.ListRightPopAsync("notifications");

📌 Hash:雜湊表(最適合存物件)

# 設定多個欄位
HSET user:1001 name "Mike" email "mike@test.com" age "30"

# 取得單一欄位
HGET user:1001 name        # "Mike"

# 取得所有欄位
HGETALL user:1001
# 1) "name"   2) "Mike"
# 3) "email"  4) "mike@test.com"
# 5) "age"    6) "30"

# 增加數值欄位
HINCRBY user:1001 age 1    # 31

.NET 程式碼範例

// Hash 操作:儲存使用者資料
var userKey = "user:1001";
await db.HashSetAsync(userKey, new HashEntry[]
{
    new("name", "Mike"),
    new("email", "mike@test.com"),
    new("age", 30)
});

// 取得單一欄位
string userName = await db.HashGetAsync(userKey, "name");

// 取得所有欄位
HashEntry[] allFields = await db.HashGetAllAsync(userKey);
foreach (var field in allFields)
    Console.WriteLine($"{field.Name}: {field.Value}");

// 數值遞增
await db.HashIncrementAsync(userKey, "age", 1);

📌 Set:無序集合(不重複)

# 新增成員
SADD tags:post:1 "csharp" "dotnet" "redis"
SADD tags:post:2 "csharp" "docker" "redis"

# 列出所有成員
SMEMBERS tags:post:1
# 1) "csharp"  2) "dotnet"  3) "redis"

# 交集(兩篇文章共同的標籤)
SINTER tags:post:1 tags:post:2
# 1) "csharp"  2) "redis"

# 聯集
SUNION tags:post:1 tags:post:2

# 是否為成員
SISMEMBER tags:post:1 "docker"  # 0 (false)

.NET 程式碼範例

// Set 操作
await db.SetAddAsync("online:users", "user:1001");
await db.SetAddAsync("online:users", "user:1002");
await db.SetAddAsync("online:users", "user:1001"); // 重複不會加入

// 取得所有線上用戶
RedisValue[] onlineUsers = await db.SetMembersAsync("online:users");

// 檢查是否在線
bool isOnline = await db.SetContainsAsync("online:users", "user:1001");

// 交集:共同好友
await db.SetAddAsync("friends:mike", new RedisValue[] { "alice", "bob", "charlie" });
await db.SetAddAsync("friends:jane", new RedisValue[] { "bob", "charlie", "dave" });
RedisValue[] mutual = await db.SetCombineAsync(SetOperation.Intersect,
    "friends:mike", "friends:jane");
// ["bob", "charlie"]

📌 Sorted Set:有序集合(排行榜神器)

# 新增成員(帶分數)
ZADD leaderboard 1500 "player:mike"
ZADD leaderboard 2000 "player:jane"
ZADD leaderboard 1800 "player:bob"

# 排名(由高到低)
ZREVRANGE leaderboard 0 -1 WITHSCORES
# 1) "player:jane"  2) "2000"
# 3) "player:bob"   4) "1800"
# 5) "player:mike"  6) "1500"

# 查排名(0-based)
ZREVRANK leaderboard "player:mike"  # 2

# 增加分數
ZINCRBY leaderboard 600 "player:mike"  # 2100

.NET 程式碼範例

// Sorted Set:排行榜
await db.SortedSetAddAsync("leaderboard", "player:mike", 1500);
await db.SortedSetAddAsync("leaderboard", "player:jane", 2000);
await db.SortedSetAddAsync("leaderboard", "player:bob", 1800);

// 取得 Top 10(分數由高到低)
var top10 = await db.SortedSetRangeByRankWithScoresAsync(
    "leaderboard", 0, 9, Order.Descending);
foreach (var entry in top10)
    Console.WriteLine($"{entry.Element}: {entry.Score}");

// 查排名
long? rank = await db.SortedSetRankAsync(
    "leaderboard", "player:mike", Order.Descending);

// 增加分數
await db.SortedSetIncrementAsync("leaderboard", "player:mike", 600);

📌 如何選擇正確的資料型態?

需要儲存簡單值或計數?     → String
需要先進先出的佇列?       → List
需要儲存物件的多個欄位?   → Hash
需要不重複的集合運算?     → Set
需要排序或排行榜?         → Sorted Set
需求 推薦型態 範例
API 回應快取 String 整個 JSON 字串
使用者 Profile Hash name, email, age 各欄位
最新 100 筆通知 List LPUSH + LTRIM
線上用戶列表 Set 自動去重
遊戲排行榜 Sorted Set 分數排序

🔑 重點整理

  1. String 是最基本的型態,支援 INCR/DECR 做計數器
  2. List 適合佇列場景,LPUSH + RPOP 就是一個簡單的 MQ
  3. Hash 最適合存物件,每個欄位獨立操作
  4. Set 用於集合運算,如交集找共同好友
  5. Sorted Set 是排行榜的最佳解,自動依分數排序

💡 大家的想法 · 0

載入中...
💬 即時聊天室 🟢 0 人在線
😀 😎 🤓 💻 🎮 🎸 🔥
➕ 新問題
📋 我的工單
💬 LINE 社群
🔒
需要註冊才能使用此功能
註冊帳號即可解鎖測驗、遊戲、簽到、筆記下載等所有功能,完全免費!
免費註冊