# 淺談 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的方式儲存

### 進階技巧, 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)