2026年9月26日
2026年9月26日
Redisのデータ型(String・Hash・List・Set)の使い分けと実例
Redis の基本データ型は String・Hash・List・Set(と、順位付きの Sorted Set)で、「保存したいデータをどう取り出したいか」で選びます。この記事では、各型の性質と代表的なコマンドを redis-cli で試しながら、キャッシュ・カウンター・キュー・タグ管理といった用途にどの型が合うか、選び間違えたときに何が起きるかを説明します。
コマンドの網羅ではなく「どの型を選ぶか」の判断材料に重点を置いています。試すときは本番ではなく、ローカルや検証用の Redis で実行してください。
前提:キーと型の関係
Redis はキーと値の組を保存するデータストアで、値の側に型があります。1つのキーは1つの型しか持てません。String として作ったキーに List 用のコマンドを使うと、次のエラーになります。
127.0.0.1:6379> SET page:views 10
OK
127.0.0.1:6379> LPUSH page:views 1
(error) WRONGTYPE Operation against a key holding the wrong kind of value
既存キーの型は TYPE で確認できます。キー名は 用途:ID:項目 のようにコロンで区切る慣習が広く使われており、後から SCAN で絞り込むときにも役立ちます。
127.0.0.1:6379> TYPE page:views
string
また、本番環境で全キーを列挙する KEYS * は、キー数が多いとサーバーを止めてしまうため避けます。代わりに SCAN 0 MATCH user:* COUNT 100 のようにカーソルで少しずつ取得します。
String:最も基本の型
String は1つのキーに1つの値を入れる型です。名前は文字列ですが、中身はバイト列なので、JSON・シリアライズしたデータ・画像の断片なども保存できます。値の上限は 512MB ですが、大きな値は転送とメモリの負担になるので、実用上は小さく保ちます。
SET cache:post:42 "{\"title\":\"Hello\",\"views\":10}" EX 300
GET cache:post:42
TTL cache:post:42
EX 300 は有効期限(秒)です。キャッシュ用途では期限を付けておくと、古いデータが残り続けたりメモリが埋まったりするのを防げます。
数値を入れた String は、INCR / INCRBY で原子的に加算できます。複数のアプリサーバーから同時に加算しても数え漏れが起きないため、アクセス数やレート制限のカウンターに向いています。
INCR counter:login_fail:203.0.113.5
EXPIRE counter:login_fail:203.0.113.5 600
SET key value NX EX 30 のように NX(キーが無いときだけ設定)を付けると、簡易的なロックとしても使えます。ただし Redis が1台構成でない場合や処理が長引く場合の扱いは難しく、ロックを本格的に使うならライブラリの実装と注意点を確認してください。
向いている用途: ページや API 応答のキャッシュ、カウンター、セッショントークンの存在確認。向かない用途: オブジェクトの一部の項目だけを頻繁に更新するデータ(毎回全体を読み書きすることになる)。
Hash:1つのキーに複数の項目を持たせる
Hash はフィールドと値の組をまとめて1つのキーに持つ型で、ユーザー情報や設定値のような「項目を持つオブジェクト」を表すのに向いています。
HSET user:1001 name "Sato" plan "basic" login_count 0
HGET user:1001 plan
HINCRBY user:1001 login_count 1
HGETALL user:1001
String に JSON を入れる方法との違いは、項目単位で読み書きできる点です。plan だけを変えたいとき、JSON なら全体を読んで書き戻す必要があり、同時更新で上書き事故が起きやすくなります。Hash なら HSET user:1001 plan "pro" だけで済みます。
注意点は有効期限です。従来、EXPIRE はキー全体(Hash 全体)にしか付けられませんでした。新しい Redis ではフィールド単位の期限を付けるコマンドも追加されていますが、使えるかどうかはサーバーのバージョン次第です(2026年10月現在)。フィールドごとに寿命が違うデータは、キーを分けるほうが扱いやすいことが多いです。
HGETALL はフィールド数が多い Hash では重くなります。大きな Hash を走査するときは HSCAN を使います。
向いている用途: ユーザープロフィール、商品の在庫や価格のような項目別に更新するデータ。向かない用途: 項目ごとに異なる有効期限を付けたいデータ、際限なくフィールドが増えるデータ。
List:順番を保った並び
List は挿入順を保つ文字列の並びで、両端への追加・取り出しが高速です。先頭に LPUSH、末尾に RPUSH、取り出しは LPOP / RPOP です。
LPUSH recent:user:1001 "post:42" "post:57"
LTRIM recent:user:1001 0 9
LRANGE recent:user:1001 0 -1
LTRIM で長さを10件に切り詰めると、「最近見た記事10件」のような上限付きの履歴になります。List は中ほどの要素への操作(インデックス指定の取得など)が要素数に比例して遅くなるので、両端を使う設計にするのがコツです。
簡単なジョブキューとしては、生産側が LPUSH、処理側が BRPOP(要素が来るまで待つブロッキング版)で取り出す形がよく使われます。
LPUSH queue:mail "{\"to\":\"user@example.com\",\"tpl\":\"welcome\"}"
BRPOP queue:mail 5
ただし、取り出した直後に処理側が落ちるとそのジョブは失われます。LMOVE で処理中リストへ移してから完了時に消す方法もありますが、再試行・確認応答・複数の消費者グループが必要なら、Redis Streams や専用のメッセージキューを検討するほうが堅実です。
向いている用途: 最新N件の履歴、タイムライン、軽量なジョブキュー。向かない用途: 重複を除きたいデータ、途中の要素を頻繁に検索・削除するデータ。
Set:重複のない集合
Set は順序を持たず、同じ値を2回入れても1つしか残らない集合です。「含まれているか」の判定と、集合同士の演算が得意です。
SADD tag:php "post:42" "post:57" "post:88"
SADD tag:security "post:57" "post:91"
SISMEMBER tag:php "post:42"
SCARD tag:php
SINTER tag:php tag:security
SINTER(共通部分)で「PHP とセキュリティの両方のタグが付いた記事」、SUNION(和集合)、SDIFF(差集合)も1コマンドで求められます。ユニーク訪問者の記録、タグ、既読フラグ、ブロックリストなどに向いています。
SMEMBERS は全要素を一度に返すので、要素数が多い Set では SSCAN を使います。また、ユニーク数を数えるだけで個々の値が不要なら、メモリ消費の小さい HyperLogLog(PFADD / PFCOUNT、誤差あり)という選択肢もあります。
向いている用途: タグ、ユニーク値の記録、所属判定、集合演算。向かない用途: 順序や順位が必要なデータ。
補足:順位が必要なら Sorted Set
Set にスコアを付けて並べたものが Sorted Set です。ランキングや、時刻をスコアにした期限付きデータの管理に使います。
ZADD ranking:weekly 120 "post:42" 95 "post:57"
ZINCRBY ranking:weekly 1 "post:57"
ZRANGE ranking:weekly 0 9 REV WITHSCORES
ZRANGE の REV オプションは比較的新しい書き方で、古いサーバーでは ZREVRANGE を使います。
用途別の選び方
迷ったときは「どう取り出すか」から逆算すると決めやすくなります。
| やりたいこと | 合う型 |
|---|---|
| 丸ごと保存して丸ごと取り出す(キャッシュ) | String |
| 数を数える | String(INCR) |
| 項目を個別に読み書きする | Hash |
| 順番どおりに積んで端から取り出す | List |
| 重複を除く・含まれるか判定する | Set |
| スコア順に並べる | Sorted Set |
WordPress でオブジェクトキャッシュに Redis を使う場合は、プラグイン側がキーと型を管理するので、自分で型を選ぶ場面はあまりありません。自作のプラグインやアプリから Redis を直接使うときに、この選び方が効いてきます。
ライセンスと互換製品について
Redis は 2024 年にライセンス形態を変更し、その後さらに見直しを行っています。この経緯から、互換のフォークである Valkey を採用するディストリビューションやクラウドサービスも出てきました(2026年10月現在)。この記事で扱った基本データ型とコマンドは両者で共通ですが、新しいコマンドの対応状況は製品とバージョンごとに異なるため、利用中のサーバーのドキュメントで確認してください。
まとめ
- 1つのキーは1つの型だけを持つ。型を取り違えると
WRONGTYPEエラーになる。TYPEで確認できる。 - String はキャッシュとカウンター、Hash は項目別に更新するオブジェクト、List は順序付きの履歴やキュー、Set は重複のない集合と集合演算に向く。
- 大きなキーの全件取得(
KEYS、HGETALL、SMEMBERS)は避け、SCAN系で少しずつ読む。 - キャッシュには有効期限を付け、信頼性の要るキューには Streams などを検討する。