# 淺談 Redis Key Naming Schemes ### 什麼是 Redis Naming Key Schemes ? * 假設你需要將相關的Key群組起來, 或是針對一個群組的Key進行管理(更新/刪除), 這時就會需要 [Key Naming Schemes](https://riptutorial.com/redis/example/13636/key-naming-schemes) 以便分類與管理, 命名範例如下: * user:10001 * user:10001:friends * 可以使用自定義的分隔符號, 如 **:** **/** **.** 等 * 不建議使用過長的key, 一個長度為1024 bytes的key在進行查找時會消耗更多的記憶體. ### Key Naming Schemes 可以做甚麼 ? * 將Key分類提升Key的可讀性, 舉例來說: * user:**profile**:10001 * user:**profile**:10002 * 透過 **wildcard** * 取得分類中的所有Key, 便能進行管理(更新Value/刪除), 參考範例如下: * python `rdb.keys(pattern='user:profile:*')` * go-redis `rdb.Client.Keys("user:profile:*")` ### 使用 Key Naming Schemes 是否影響效能 ? * GetKeys 是 O(N) 的操作, 可能造成 block, 特別是在 cluster mode 時會更糟糕 * 使用工具查詢時會有一種數據被directory tree化的錯覺(如下圖), 但實際上數據還是以KV的方式儲存 ![](https://i.imgur.com/Vk8ek2S.png) ### 進階技巧, Sort * 儲存`MEMBER:SCORE:0731:xxxxx`時, 一併將 `xxxxx` 存入`MEMBER:SCORE:0731_LIST`的 List 結構中, 然後對 `List` 使用 Sort func 取出 key`("MEMBER:SCORE:0731:*")`的排序結果 ``` sort := &redis.Sort{ By: "MEMBER:SCORE:0731:*", Offset: 0, Count: 10, Order: "DESC", } result, err := client.Sort("MEMBER:SCORE:0731_LIST", sort).Result() if err != nil { return err } ``` * 補充說明, 建議使用 [有序集合 Sorted Set](https://www.gushiciku.cn/pl/gR2j/zh-tw)