Redisのデータ型概要
Redisは5つの基本データ型をサポートしており、それぞれに独自の特性とユースケースがあります。このレッスンでは、すべてのデータ型の概要を説明します。
Redisのデータ型概要
| データ型 | 説明 | 内部実装 | ユースケース |
|---|---|---|---|
| String | 最も基本的な型。文字列、整数、バイナリデータを保存 | SDS(Simple Dynamic String) | キャッシュ、カウンター、分散ロック |
| Hash | キーと値のコレクション。Map/Objectのようなもの | ハッシュテーブル + ziplist | オブジェクトの保存、ショッピングカート |
| List | 順序付けられた、重複可能な文字列のリスト | 双方向リンクリスト + ziplist | メッセージキュー、最新リスト |
| Set | 順序なしの、一意な文字列のコレクション | ハッシュテーブル + intset | タグ、ソーシャル関係 |
| Sorted Set | 順序付けられた、要素ごとにスコアを持つ一意なコレクション | スキップリスト + ハッシュテーブル | リーダーボード、重み付きコレクション |
💡 Redisが高速な理由は? すべてのデータがメモリにあり、効率的なデータ構造(ハッシュテーブル、スキップリストなど)を使用しています。
String
Stringは最も基本的なRedisデータ型です。以下のものを保存できます:
- 文字列(テキスト)
- 整数(数値)
- バイナリデータ(画像、シリアライズされたオブジェクト)
特徴
- バイナリセーフ:あらゆるデータ(画像、動画など)を保存可能
- 最大サイズ:512MB
- 数値演算をサポート:INCR、DECR、INCRBYなど
- ビット演算をサポート:SETBIT、GETBIT、BITCOUNTなど
基本コマンド
REDIS
# 設定と取得
SET key value
GET key
# 数値演算
INCR key # 1増加
INCRBY key 10 # 10増加
DECR key # 1減少
# その他の操作
APPEND key suffix # 追加
STRLEN key # 長さを取得
ユースケース
| シナリオ | 例 |
|---|---|
| キャッシュ | SET user:1:profile '{"name":"Alice"}' |
| カウンター | INCR article:123:views |
| 分散ロック | SET lock:resource "locked" NX EX 10 |
| セッション | SET session:token123 "user_data" EX 3600 |
💡 分散ロックの原理: SETコマンドのNXパラメータ(キーが存在しない場合のみ設定)とEX(有効期限)を組み合わせることで、アトミックなロック取得を実現します。
Hash
Hashはキーと値のコレクションで、プログラミング言語のMapやDictionary、Objectに似ています。
特徴
- オブジェクトの保存(ユーザー情報、商品情報など)に最適
- オブジェクト全体を読み取らずに個々のフィールドを変更可能
- メモリ効率が良い(少量データではziplistを使用)
基本コマンド
REDIS
# フィールドの設定と取得
HSET user:1 name "Alice"
HSET user:1 age 25
HGET user:1 name # "Alice"
# 複数フィールドの設定
HMSET user:2 name "Bob" age 30 city "Beijing"
# すべてのフィールドと値を取得
HGETALL user:2
# 1) "name"
# 2) "Bob"
# 3) "age"
# 4) "30"
# 5) "city"
# 6) "Beijing"
# 複数フィールドの取得
HMGET user:2 name age
# 1) "Bob"
# 2) "30"
# フィールドの削除
HDEL user:2 city
# フィールドの存在確認
HEXISTS user:2 name # 1
# すべてのフィールド名を取得
HKEYS user:2
# 1) "name"
# 2) "age"
# すべての値を取得
HVALS user:2
# 1) "Bob"
# 2) "30"
# フィールド数を取得
HLEN user:2 # 2
ユースケース
| シナリオ | 例 |
|---|---|
| オブジェクトの保存 | HSET user:1 name "Alice" age 25 email "alice@example.com" |
| ショッピングカート | HSET cart:user1 product:101 2 product:102 1(商品IDと数量) |
| カウンターグループ | HINCRBY article:123 likes 1 |
オブジェクト保存におけるHash vs String
方法1:String + JSON
REDIS
SET user:1 '{"name":"Alice","age":25,"email":"alice@example.com"}'
- メリット:シンプル
- デメリット:1つのフィールドを変更するには、オブジェクト全体を読み取り、変更し、書き戻す必要がある
方法2:Hash
REDIS
HSET user:1 name "Alice" age 25 email "alice@example.com"
- メリット:個々のフィールドを独立して変更可能
- デメリット:複雑なネスト構造をサポートしない
💡 推奨: シンプルなオブジェクトにはHash、複雑なネストオブジェクトにはString + JSONを使用してください。
List
Listは順序付けられた文字列のシーケンスで、重複要素を許可します。
特徴
- 順序付け:要素は挿入順序を保持
- 重複可能:同じ値が複数回出現可能
- 両端操作:両端からプッシュとポップが可能
- 最大長:2^32 - 1(約42億)
基本コマンド
REDIS
# 左側(先頭)に挿入
LPUSH mylist "a" "b" "c" # リストの長さを返す
# 右側(末尾)に挿入
RPUSH mylist "d" "e"
# リストの長さを取得
LLEN mylist # 5
# 範囲内の要素を取得
LRANGE mylist 0 -1 # すべての要素を取得
# 1) "c"
# 2) "b"
# 3) "a"
# 4) "d"
# 5) "e"
# 特定のインデックスの要素を取得
LINDEX mylist 0 # "c"(最初の要素)
# 左側(先頭)からポップ
LPOP mylist # "c"
# 右側(末尾)からポップ
RPOP mylist # "e"
# 特定のインデックスの要素を設定
LSET mylist 0 "new"
# 値による要素の削除
LREM mylist 1 "a" # 値が"a"の要素を1つ削除
ユースケース
| シナリオ | 説明 |
|---|---|
| メッセージキュー | LPUSH + RPOP または RPUSH + LPOP |
| 最新リスト | 最新の記事、最近のコメント |
| タイムライン | ユーザーのフィード、マイクロブログのタイムライン |
例:メッセージキュー
BASH
# プロデューサー:キューにメッセージをプッシュ
LPUSH queue:email "send to user1"
LPUSH queue:email "send to user2"
# コンシューマー:キューからメッセージをポップ
RPOP queue:email
RPOP queue:email
# ブロッキングポップ(メッセージがないときはブロック)
BRPOP queue:email 10
💡 LPUSH + RPOP = キュー(FIFO)、LPUSH + LPOP = スタック(LIFO)
Set
Setは順序なしの一意な文字列のコレクションです。
特徴
- 順序なし:要素に特定の順序はない
- 一意:自動的に重複を排除
- 集合演算をサポート:積集合、和集合、差集合
基本コマンド
REDIS
# 要素の追加
SADD myset "a" "b" "c"
# すべての要素を取得
SMEMBERS myset
# 1) "a"
# 2) "b"
# 3) "c"
# 要素の存在確認
SISMEMBER myset "a" # 1(存在する)
# 要素の削除
SREM myset "a"
# セットのサイズを取得
SCARD myset # 2
# ランダムな要素を取得
SRANDMEMBER myset
# ランダムな要素をポップ
SPOP myset
集合演算
REDIS
# 2つのセットを作成
SADD set1 "a" "b" "c"
SADD set2 "b" "c" "d"
# 積集合(両方のセットに存在する要素)
SINTER set1 set2
# 1) "b"
# 2) "c"
# 和集合(どちらかのセットに存在する要素)
SUNION set1 set2
# 1) "a"
# 2) "b"
# 3) "c"
# 4) "d"
# 差集合(set1にあってset2にない要素)
SDIFF set1 set2
# 1) "a"
# 結果を新しいセットに保存
SINTERSTORE result set1 set2
ユースケース
| シナリオ | 説明 |
|---|---|
| タグシステム | ユーザータグ、記事タグ |
| ソーシャル関係 | フレンドリスト、フォローリスト |
| 相互フォロー | 2人のユーザーのフレンドセットの積集合 |
| レコメンデーションシステム | 知り合いかもしれません = 友達の友達 - 自分の友達 - 自分 |
例:相互フォロー
BASH
# ユーザー1の友達
SADD friends:user1 "Alice" "Bob" "Charlie"
# ユーザー2の友達
SADD friends:user2 "Bob" "Charlie" "David"
# 相互フォロー
SINTER friends:user1 friends:user2
Sorted Set
Sorted Setはスコアを持つコレクションで、要素はスコアでソートされます。
特徴
- 順序付け:要素はスコアでソート(昇順)
- 一意:要素は一意だが、スコアは重複可能
- 範囲クエリをサポート:スコアまたはランクによる
基本コマンド
REDIS
# 要素の追加(スコア付き)
ZADD leaderboard 100 "Alice"
ZADD leaderboard 95 "Bob"
ZADD leaderboard 98 "Charlie"
# 要素のスコアを取得
ZSCORE leaderboard "Alice" # "100"
# 要素のランクを取得(0ベース、スコア昇順)
ZRANK leaderboard "Alice" # 2(3位)
# 要素のランクを取得(スコア降順)
ZREVRANK leaderboard "Alice" # 0(1位)
# ランク範囲で要素を取得(昇順)
ZRANGE leaderboard 0 -1 WITHSCORES
# 1) "Bob"
# 2) "95"
# 3) "Charlie"
# 4) "98"
# 5) "Alice"
# 6) "100"
# ランク範囲で要素を取得(降順)
ZREVRANGE leaderboard 0 -1 WITHSCORES
# 1) "Alice"
# 2) "100"
# 3) "Charlie"
# 4) "98"
# 5) "Bob"
# 6) "95"
# スコア範囲で要素を取得
ZRANGEBYSCORE leaderboard 95 100 WITHSCORES
# 要素のスコアを増加
ZINCRBY leaderboard 5 "Bob" # Bobのスコアが100になる
# 要素の削除
ZREM leaderboard "Bob"
# セットのサイズを取得
ZCARD leaderboard
# スコア範囲内の要素をカウント
ZCOUNT leaderboard 90 100
ユースケース
| シナリオ | 説明 |
|---|---|
| リーダーボード | ゲームのリーダーボード、トレンドリスト |
| 重み付きタグ | タグ + 重み |
| 遅延キュー | スコアは実行タイムスタンプ |
| スライディングウィンドウ | 時間枠内のデータ統計 |
例:ゲームリーダーボード
BASH
# プレイヤースコアを更新
ZADD game:leaderboard 1500 "player1"
ZADD game:leaderboard 2300 "player2"
ZADD game:leaderboard 1800 "player3"
# トップ10を取得
ZREVRANGE game:leaderboard 0 9 WITHSCORES
# プレイヤーランクを取得
ZREVRANK game:leaderboard "player1"
# スコアが1000〜2000のプレイヤーを取得
ZRANGEBYSCORE game:leaderboard 1000 2000 WITHSCORES
データ型選択ガイド
決定木
何を保存する必要がありますか?
├─ 単一の値(文字列、数値、バイナリ)
│ └─ Stringを使用
│
├─ オブジェクト(複数フィールド)
│ ├─ フィールドを個別に変更することが多い
│ │ └─ Hashを使用
│ └─ フィールドを個別に変更することがほとんどない
│ └─ String(JSON)を使用
│
├─ 順序付きリスト
│ ├─ 両端操作が必要
│ │ └─ Listを使用
│ └─ スコアによるソートが必要
│ └─ Sorted Setを使用
│
└─ 順序なしコレクション
├─ 重複排除が必要
│ └─ Setを使用
└─ 重複排除 + ソートが必要
└─ Sorted Setを使用
比較まとめ
| 機能 | String | Hash | List | Set | Sorted Set |
|---|---|---|---|---|---|
| 順序付け | - | - | ✓ | ✗ | ✓ |
| 重複可能 | - | - | ✓ | ✗ | ✗ |
| 数値演算 | ✓ | ✓ | ✗ | ✗ | ✓ |
| 集合演算 | ✗ | ✗ | ✗ | ✓ | ✗ |
| 範囲クエリ | ✗ | ✗ | ✓ | ✗ | ✓ |
| 単一フィールド変更 | ✗ | ✓ | ✗ | ✗ | ✗ |
TYPEコマンド
TYPEコマンドを使用してキーのデータ型を確認します:
REDIS
SET mystring "hello"
TYPE mystring # string
HSET myhash field "value"
TYPE myhash # hash
LPUSH mylist "a"
TYPE mylist # list
SADD myset "a"
TYPE myset # set
ZADD myzset 1 "a"
TYPE myzset # zset
❓ よくある質問
Q Stringはどのくらいのデータを保存できますか?
A 最大512MBです。ただし、非常に大きなデータを保存するとパフォーマンスに影響するため、推奨されません。
Q オブジェクトの保存にはHashとStringのどちらが良いですか?
A シンプルなオブジェクト(個々のフィールドを変更できる)にはHash、複雑なネストオブジェクトにはString(JSON)を使用します。
Q Listにはいくつの要素を保存できますか?
A 最大2^32-1(約42億)ですが、実際には利用可能なメモリによって制限されます。
Q SetとListの違いは何ですか?
A Setは順序なしで要素は一意です。Listは順序付けられており、重複を許可します。重複排除にはSet、順序付きシーケンスにはListを使用します。
Q Sorted Setのスコアは小数にできますか?
A はい、スコアは倍精度浮動小数点数です。
📖 まとめ
- Redisには5つの基本データ型があります:String、Hash、List、Set、Sorted Set
- String:最も基本的で、文字列、整数、バイナリを保存
- Hash:キーと値のコレクション、オブジェクトに最適
- List:順序付きリスト、メッセージキューや最新リストに最適
- Set:順序なしコレクション、集合演算をサポート
- Sorted Set:順序付きコレクション、リーダーボードに最適
- ユースケースに基づいて適切なデータ型を選びましょう
📝 練習問題
- データを作成: 各データ型のサンプルデータを作成しましょう
- TYPEコマンド: TYPEを使用して作成したデータ型を確認しましょう
- シナリオ思考: eコマースサイトの場合、商品情報、ショッピングカート、注文リストにはそれぞれどのデータ型を使用しますか?
- 集合演算: 2人のユーザーのフォローリストを作成し、相互フォローを計算しましょう
次のレッスン
次のレッスンでは、Redisのキー管理について学びます。キー操作と管理について詳しく解説します。



