Recommendation
Profile cache: use a Hash per user. Leaderboard: use a Sorted Set per board.
User profile: Hash
The JSON string forces fetch, parse, mutate and rewrite for every change. A Hash lets you touch one field at a time:
HSET user:1001:profile name "Ada" email "[email protected]" level 42 country "DE"
HSET user:1001:profile email "[email protected]" # update one field, no read needed
HGET user:1001:profile email # read one field
HGETALL user:1001:profile # read everything
HINCRBY user:1001:profile level 1 # atomic numeric update
EXPIRE user:1001:profile 3600 # TTL, since this is a cache
This is atomic, needs no read-modify-write cycle, and avoids lost updates when two writers race. It also sends far less data over the wire.
Hashes hold flat field/value pairs. If the profile has nested data, such as arrays of items or sub-objects, use the JSON type (JSON.SET user:1001:profile $.address.city '"Berlin"'). Otherwise a Hash is simpler and lighter. You can also keep rarely changed nested parts in a separate key, for example user:1001:settings.
Leaderboard: Sorted Set
ZADD game:space-invaders:leaderboard 12500 user:1001 # set/update score
ZINCRBY game:space-invaders:leaderboard 300 user:1001 # add points atomically
ZREVRANGE game:space-invaders:leaderboard 0 9 WITHSCORES # top 10
ZREVRANK game:space-invaders:leaderboard user:1001 # a player's rank
The member should be the user ID, not the whole profile. To render the board, take the top N IDs and fetch each profile with HMGET or HGETALL, pipelined.
Key naming
Use lowercase, colon-separated keys in the form {entity}:{id}:{attribute}. User_1001_Profile breaks that convention in casing, separators and order.
| Purpose | Key |
|---|---|
| Profile | user:1001:profile |
| Settings | user:1001:settings |
| Global leaderboard | game:space-invaders:leaderboard |
| Periodic board | game:space-invaders:leaderboard:2026-w43 |
| Session | session:abc123 |
Further tips:
- Keep keys short, because they live in memory and appear in every command.
- Pick one convention and apply it everywhere.
- If you're multi-tenant, prefix with the tenant (
tenant:42:user:1001:profile). That makes scans and ACLs easy to scope. - Time-bucketed leaderboard keys such as weekly or daily boards can be expired or rotated with
EXPIRE.
Migration
- Write a one-off script that reads each
User_*_Profilestring, parses it and doesHSET user:{id}:profile .... - Have the app write to the new keys, or dual-write briefly.
- Delete the old keys once reads are fully switched over. Use
SCANfor this, neverKEYS.
I can sketch the migration script or the client code in Python or Java if that would help.
Pure-instruction skill, so the trial gave the model only the Skill and Read tools: no network, no shell, no Redis server. The request mixes a data-model question with a key-renaming question.
できること
Redis, Inc. の推奨に沿ってデータを設計するようモデルに指示します。データ型はアクセスパターンに合わせ、キーは短く小文字でコロン区切り(例:user:1001:profile)にします。
仕組み
- カウンター、オブジェクト、キュー、重複なし集合、ランキング、ネストしたデータ、イベントログ、ベクトルといった用途を、判断表で Redis の型に対応付けます。
- 平坦なオブジェクトを1つの文字列にシリアライズするアンチパターンを示し、Hash を使う書き方を Python(redis-py)と Java(Jedis)で紹介します。
- キー命名の規則を示します:
{エンティティ}:{id}:{属性}、空白や大文字小文字の混在は避ける、URL をそのままキーにしない、マルチテナントならテナントのプレフィックスを付ける。
向いている場面
Redis のデータモデル設計、オブジェクトやセッションのキャッシュ、カウンターやランキングの実装、バラバラなキー名の整理。
制限
非常に短い Skill です(参照ファイル2つで約 7 KB)。扱うのはデータ型とキー名のみで、クラスタ、永続化、検索は対象外です。
低リスク:Redis 公式リポジトリ(MIT ライセンス)の指示ファイルのみで、スクリプトなし、ネットワーク通信なし、ファイル書き込みなし、アカウントやキーも不要です。助言をするだけで、あなたの Redis には接続しません。移行に関する提案は、自分のデータで確認してから実行してください。