Redis コマンド 100 本ノック:Key/Hash/List/Set/ZSet/Stream 早見表

Redis を使いこなすには、基本コマンドの習得が欠かせません。この記事では、Redis の主要データ構造である Key、Hash、List、Set、Sorted Set(ZSet)、Stream について、実務で役立つコマンドを 100 個厳選してご紹介します。
初心者の方でも理解しやすいよう、各コマンドに具体例とコメントを添えて解説していますので、辞書のようにお使いいただけます。Redis を使い始めたばかりの方も、この記事を読めば即座に実践できるようになるでしょう。
記事内容の早見表
この記事で紹介する Redis コマンドの全体像を、データ構造ごとにまとめました。
データ構造 | コマンド数 | 主な用途 | 代表的なコマンド |
---|---|---|---|
Key / String | 15 本 | セッション、カウンター、キャッシュ | SET, GET, INCR, DECR, MSET, MGET, EXPIRE, TTL |
Hash | 15 本 | ユーザー情報、設定データ | HSET, HGET, HGETALL, HMGET, HINCRBY, HDEL |
List | 20 本 | タイムライン、キュー、スタック | LPUSH, RPUSH, LPOP, RPOP, LRANGE, BLPOP, BRPOP |
Set | 15 本 | タグ、ユニークユーザー | SADD, SREM, SMEMBERS, SINTER, SUNION, SDIFF |
Sorted Set(ZSet) | 20 本 | ランキング、優先度キュー | ZADD, ZRANGE, ZREVRANGE, ZRANK, ZINCRBY, ZPOPMIN, ZPOPMAX |
Stream | 15 本 | イベントログ、メッセージング | XADD, XRANGE, XREAD, XREADGROUP, XACK, XPENDING |
合計 | 100 本 | - | Redis の実務で必要な主要コマンドを網羅 |
各データ構造の詳細なコマンドリストは、本文中の該当セクションをご参照ください。
背景
Redis のデータ構造とは
Redis(Remote Dictionary Server)は、高速なインメモリデータストアとして広く利用されています。その特徴は、単なる Key-Value ストアではなく、多様なデータ構造を提供している点です。
Redis が提供する主なデータ構造は以下の 6 種類になります。
# | データ構造 | 用途 | 代表的な使用例 |
---|---|---|---|
1 | String(Key) | 単純な値の保存 | セッション管理、カウンター |
2 | Hash | フィールドと値のマッピング | ユーザー情報、設定データ |
3 | List | 順序付きリスト | タイムライン、キュー |
4 | Set | 重複のない集合 | タグ管理、ユニークユーザー |
5 | Sorted Set(ZSet) | スコア付き集合 | ランキング、優先度キュー |
6 | Stream | ログ型データ | イベントストリーム、メッセージング |
以下の図は、Redis のデータ構造と典型的な利用シーンの関係を示しています。
mermaidflowchart TB
redis["Redis サーバー"]
redis --> string["String/Key<br/>シンプルな値"]
redis --> hash["Hash<br/>構造化データ"]
redis --> list["List<br/>順序付きデータ"]
redis --> set["Set<br/>ユニーク集合"]
redis --> zset["Sorted Set<br/>スコア付き集合"]
redis --> stream["Stream<br/>ログストリーム"]
string --> use1["セッション/カウンター"]
hash --> use2["ユーザー情報"]
list --> use3["タイムライン/キュー"]
set --> use4["タグ/フォロワー"]
zset --> use5["ランキング"]
stream --> use6["イベントログ"]
図で理解できる要点:
- Redis は 6 種類の主要データ構造を提供
- それぞれ異なるユースケースに最適化されている
- 用途に応じて適切なデータ構造を選択することが重要
なぜコマンドの習得が重要なのか
Redis の真価を発揮させるには、各データ構造に適したコマンドを使いこなす必要があります。例えば、ランキング機能を実装する際、List ではなく Sorted Set を使うことで、パフォーマンスが大きく向上します。
また、Redis は GUI ツールも存在しますが、実務では CLI やプログラムからのコマンド実行が主流です。コマンドを体系的に理解しておくことで、トラブルシューティングや最適化がスムーズに行えるようになります。
課題
Redis 学習者が直面する問題
Redis を学び始めた方が直面する典型的な課題として、以下のようなものがあります。
1. コマンドが多すぎて覚えられない
Redis には 200 以上のコマンドが存在し、どれから学べばよいか迷ってしまいます。公式ドキュメントは網羅的ですが、実務で頻繁に使うコマンドとそうでないコマンドの区別がつきにくいのです。
2. データ構造ごとの使い分けがわからない
String、Hash、List など、どの場面でどのデータ構造を使うべきか判断が難しく感じられます。特に Hash と単純な Key の使い分けや、List と Set の違いなど、初学者には分かりにくい部分があります。
3. 実践的な使用例が不足している
コマンドのシンタックスは理解できても、実際のアプリケーションでどう活用するのか具体的なイメージが湧きにくいという声が多く聞かれます。
以下の図は、学習者が Redis を習得する際の典型的な課題フローを示しています。
mermaidflowchart LR
start["Redis 学習開始"] --> problem1["200以上の<br/>コマンド"]
problem1 --> confusion1["何から学ぶ?"]
start --> problem2["6種類の<br/>データ構造"]
problem2 --> confusion2["どう使い分ける?"]
start --> problem3["公式ドキュメント<br/>参照"]
problem3 --> confusion3["実例が少ない"]
confusion1 --> result["学習効率低下"]
confusion2 --> result
confusion3 --> result
図で理解できる要点:
- 初学者は「選択肢の多さ」「使い分けの難しさ」「実例不足」の 3 つの壁に直面
- これらが複合的に学習効率を低下させる
- 体系的な学習ガイドが必要
よくある失敗パターン
実務でよく見られる失敗例として、以下のようなケースがあります。
- List で実装すべき機能を String の連結で無理やり実装してしまう
- Sorted Set を知らずに、自前でソート処理を実装してパフォーマンスが悪化する
- Stream の存在を知らず、Pub/Sub だけでメッセージングを実装して機能不足に陥る
これらの問題は、Redis の各データ構造とコマンドを体系的に学ぶことで解決できます。
解決策
100 本ノック形式での学習アプローチ
この記事では、Redis の実務で頻繁に使用するコマンドを 100 個厳選 し、データ構造ごとに分類して紹介します。各コマンドには以下の情報を含めています。
- コマンド名と基本構文:正確なシンタックス
- 具体的な実行例:実際に動作するコード
- 詳細なコメント:各行の処理内容
- 実務での活用シーン:どんな場面で使うか
以下の図は、本記事での学習フローを示しています。
mermaidflowchart TD
start["100本ノック開始"] --> category["データ構造別<br/>6カテゴリ"]
category --> key["Key/String<br/>15コマンド"]
category --> hash["Hash<br/>15コマンド"]
category --> list["List<br/>20コマンド"]
category --> set_cmds["Set<br/>15コマンド"]
category --> zset["Sorted Set<br/>20コマンド"]
category --> stream["Stream<br/>15コマンド"]
key --> practice["実践練習"]
hash --> practice
list --> practice
set_cmds --> practice
zset --> practice
stream --> practice
practice --> master["Redis<br/>コマンド習得"]
図で理解できる要点:
- 100 コマンドを 6 つのデータ構造に分類
- 各カテゴリで実務に必要な主要コマンドをカバー
- 段階的に学習することで確実に習得可能
学習の進め方
各セクションは独立していますので、興味のあるデータ構造から学び始めることができます。ただし、Key/String は Redis の基礎となりますので、最初に学習することをおすすめします。
実際に手を動かして試すことで、コマンドの動作を体感できます。Redis をローカル環境にインストールし、redis-cli を使って一つずつ実行してみてください。
具体例
それでは、データ構造ごとに実務で役立つコマンドを見ていきましょう。
1. Key / String コマンド(15 本)
String 型は Redis の最も基本的なデータ構造です。単純な値の保存から、数値の増減、ビット操作まで幅広い用途に使えます。
1-1. SET - 値の設定
redis# 基本的な SET コマンド
SET user:1000:name "田中太郎"
# => OK
# EX オプションで有効期限を秒単位で設定(セッション管理に便利)
SET session:abc123 "user_data" EX 3600
# => OK(1時間後に自動削除)
# NX オプションで存在しない場合のみ設定(重複防止)
SET lock:resource1 "locked" NX EX 30
# => OK(既に存在する場合は nil)
SET コマンドは Redis で最も頻繁に使用されるコマンドです。EX オプションを使うことで、セッション管理やキャッシュの自動削除が簡単に実装できます。
1-2. GET - 値の取得
redis# 単純な値の取得
GET user:1000:name
# => "田中太郎"
# 存在しないキーの取得
GET user:9999:name
# => (nil)
GET は SET で保存した値を取得します。存在しないキーの場合は nil が返されます。
1-3. MSET / MGET - 複数の値を一括操作
redis# 複数の値を一度に設定(ネットワークラウンドトリップを削減)
MSET user:1001:name "佐藤花子" user:1001:age "28" user:1001:city "東京"
# => OK
# 複数の値を一度に取得
MGET user:1001:name user:1001:age user:1001:city
# => 1) "佐藤花子"
# => 2) "28"
# => 3) "東京"
MSET と MGET を使うことで、複数のキーを効率的に操作できます。特にネットワーク越しの Redis 操作では、パフォーマンス向上に大きく貢献します。
1-4. INCR / DECR - 数値の増減
redis# カウンターの初期化と増加
SET page:views 0
# => OK
INCR page:views
# => (integer) 1
INCR page:views
# => (integer) 2
# 指定値だけ増加
INCRBY page:views 10
# => (integer) 12
# 減少
DECR page:views
# => (integer) 11
DECRBY page:views 5
# => (integer) 6
INCR/DECR はアトミックな操作として実行されるため、並行処理環境でも安全にカウンターを管理できます。
1-5. APPEND - 文字列の追加
redis# 文字列の末尾に追加
SET log:001 "2025-01-01: Start"
# => OK
APPEND log:001 " | Processing"
# => (integer) 28(文字列の長さ)
GET log:001
# => "2025-01-01: Start | Processing"
APPEND は既存の文字列に新しい値を追加します。ログの追記などに便利です。
1-6. STRLEN - 文字列長の取得
redis# 文字列の長さを取得
STRLEN log:001
# => (integer) 28
# 存在しないキーの場合
STRLEN nonexistent
# => (integer) 0
1-7. GETRANGE - 部分文字列の取得
redis# 文字列の一部を取得(0始まりのインデックス)
SET message "Hello Redis World"
# => OK
GETRANGE message 0 4
# => "Hello"
GETRANGE message 6 10
# => "Redis"
# 負のインデックスで末尾から指定
GETRANGE message -5 -1
# => "World"
GETRANGE を使うと、文字列の一部だけを効率的に取得できます。
1-8. SETRANGE - 部分文字列の置換
redis# 文字列の一部を置換
SETRANGE message 6 "World"
# => (integer) 17
GET message
# => "Hello World orld"
1-9. GETSET - 値の取得と設定を同時実行
redis# 古い値を取得しつつ新しい値を設定
SET counter "100"
# => OK
GETSET counter "200"
# => "100"(古い値が返される)
GET counter
# => "200"
GETSET は、現在の値を取得しながら新しい値に更新します。アトミックな操作のため、排他制御が不要です。
1-10. SETNX - 存在しない場合のみ設定
redis# キーが存在しない場合のみ設定(分散ロックに利用)
SETNX lock:resource1 "process_id_123"
# => (integer) 1(設定成功)
SETNX lock:resource1 "process_id_456"
# => (integer) 0(既に存在するため失敗)
SETNX は分散ロックの実装によく使われます。ただし、現在は SET コマンドの NX オプション使用が推奨されています。
1-11. EXPIRE / TTL - 有効期限の設定と確認
redis# キーに有効期限を設定(秒単位)
SET cache:data "temporary_value"
# => OK
EXPIRE cache:data 300
# => (integer) 1(設定成功)
# 残り時間の確認
TTL cache:data
# => (integer) 295(残り秒数)
# 期限なしのキーの場合
TTL user:1000:name
# => (integer) -1
# 存在しないキーの場合
TTL nonexistent
# => (integer) -2
EXPIRE は既存のキーに有効期限を設定します。TTL で残り時間を確認できます。
1-12. PEXPIRE / PTTL - ミリ秒単位の有効期限
redis# ミリ秒単位で有効期限を設定
PEXPIRE cache:data 500000
# => (integer) 1
# ミリ秒単位で残り時間を確認
PTTL cache:data
# => (integer) 495000
より精密な制御が必要な場合は、PEXPIRE と PTTL を使います。
1-13. PERSIST - 有効期限の削除
redis# 有効期限を削除して永続化
PERSIST cache:data
# => (integer) 1
TTL cache:data
# => (integer) -1(期限なし)
1-14. EXISTS - キーの存在確認
redis# キーの存在を確認
EXISTS user:1000:name
# => (integer) 1(存在する)
EXISTS user:9999:name
# => (integer) 0(存在しない)
# 複数キーの存在確認
EXISTS user:1000:name user:1001:name user:9999:name
# => (integer) 2(存在するキーの数)
EXISTS は指定したキーが存在するか確認します。複数指定した場合は存在するキーの数を返します。
1-15. DEL - キーの削除
redis# キーを削除
DEL user:1000:name
# => (integer) 1(削除したキーの数)
# 複数キーを同時削除
DEL user:1001:name user:1001:age user:1001:city
# => (integer) 3
DEL は指定したキーを削除します。複数のキーを一度に削除することも可能です。
2. Hash コマンド(15 本)
Hash は、フィールドと値のペアを格納するデータ構造です。オブジェクトやレコードのような構造化データを効率的に扱えます。
2-1. HSET - フィールドの設定
redis# Hash に単一フィールドを設定
HSET user:2000 name "山田一郎"
# => (integer) 1(新規作成された場合)
# 複数フィールドを同時設定
HSET user:2000 age "35" email "yamada@example.com" city "大阪"
# => (integer) 3
HSET は Hash にフィールドと値を設定します。Redis 4.0 以降では、一度に複数のフィールドを設定できるようになりました。
2-2. HGET - フィールドの取得
redis# 単一フィールドの値を取得
HGET user:2000 name
# => "山田一郎"
# 存在しないフィールドの場合
HGET user:2000 phone
# => (nil)
2-3. HMGET - 複数フィールドの取得
redis# 複数フィールドを一度に取得
HMGET user:2000 name age email
# => 1) "山田一郎"
# => 2) "35"
# => 3) "yamada@example.com"
HMGET を使うことで、必要なフィールドだけを効率的に取得できます。
2-4. HGETALL - 全フィールドの取得
redis# Hash の全フィールドと値を取得
HGETALL user:2000
# => 1) "name"
# => 2) "山田一郎"
# => 3) "age"
# => 4) "35"
# => 5) "email"
# => 6) "yamada@example.com"
# => 7) "city"
# => 8) "大阪"
HGETALL は Hash の全データを取得します。ただし、フィールド数が多い場合はパフォーマンスに注意が必要です。
2-5. HDEL - フィールドの削除
redis# 単一フィールドを削除
HDEL user:2000 city
# => (integer) 1
# 複数フィールドを同時削除
HDEL user:2000 email phone
# => (integer) 1(実際に削除されたフィールド数)
2-6. HEXISTS - フィールドの存在確認
redis# フィールドの存在を確認
HEXISTS user:2000 name
# => (integer) 1(存在する)
HEXISTS user:2000 city
# => (integer) 0(存在しない)
HEXISTS は、指定したフィールドが Hash に存在するか確認します。
2-7. HKEYS - 全フィールド名の取得
redis# Hash の全フィールド名を取得
HKEYS user:2000
# => 1) "name"
# => 2) "age"
HKEYS はフィールド名のみをリスト形式で取得します。値は含まれません。
2-8. HVALS - 全値の取得
redis# Hash の全値を取得
HVALS user:2000
# => 1) "山田一郎"
# => 2) "35"
HVALS は値のみを取得します。どの値がどのフィールドのものか判別できない点に注意してください。
2-9. HLEN - フィールド数の取得
redis# Hash のフィールド数を取得
HLEN user:2000
# => (integer) 2
HLEN は Hash に含まれるフィールドの総数を返します。
2-10. HINCRBY - 数値フィールドの増減
redis# 数値フィールドを増加
HSET user:2000 login_count "0"
# => (integer) 1
HINCRBY user:2000 login_count 1
# => (integer) 1
HINCRBY user:2000 login_count 5
# => (integer) 6
# 負の値で減少
HINCRBY user:2000 login_count -2
# => (integer) 4
HINCRBY は Hash 内の数値フィールドをアトミックに増減させます。
2-11. HINCRBYFLOAT - 浮動小数点数の増減
redis# 小数点を含む数値の増減
HSET product:100 price "1500.50"
# => (integer) 1
HINCRBYFLOAT product:100 price 250.25
# => "1750.75"
HINCRBYFLOAT product:100 price -50.50
# => "1700.25"
HINCRBYFLOAT は浮動小数点数の計算に対応します。価格計算などに便利です。
2-12. HSETNX - 存在しない場合のみ設定
redis# フィールドが存在しない場合のみ設定
HSETNX user:2000 created_at "2025-01-01"
# => (integer) 1(設定成功)
HSETNX user:2000 created_at "2025-01-02"
# => (integer) 0(既に存在するため失敗)
HSETNX は、フィールドが存在しない場合のみ値を設定します。初期値設定に便利です。
2-13. HSTRLEN - フィールド値の文字列長
redis# フィールド値の文字列長を取得
HSTRLEN user:2000 name
# => (integer) 12(バイト数)
2-14. HSCAN - Hash の反復処理
redis# Hash の内容をカーソルベースで取得(大量データに対応)
HSCAN user:2000 0
# => 1) "0"(次のカーソル、0は終了を意味する)
# => 2) 1) "name"
# => 2) "山田一郎"
# => 3) "age"
# => 4) "35"
# パターンマッチングで特定フィールドのみ取得
HSCAN user:2000 0 MATCH *name*
# => 1) "0"
# => 2) 1) "name"
# => 2) "山田一郎"
HSCAN は大量のフィールドを持つ Hash を効率的に走査できます。HGETALL と異なり、メモリ負荷を抑えられます。
2-15. HRANDFIELD - ランダムフィールドの取得
redis# ランダムにフィールド名を取得
HRANDFIELD user:2000
# => "name"(ランダムに選ばれる)
# 複数のランダムフィールドを取得
HRANDFIELD user:2000 2
# => 1) "age"
# => 2) "name"
# 値も含めて取得
HRANDFIELD user:2000 2 WITHVALUES
# => 1) "age"
# => 2) "35"
# => 3) "name"
# => 4) "山田一郎"
HRANDFIELD はランダムサンプリングに便利です(Redis 6.2 以降)。
3. List コマンド(20 本)
List は順序付きの要素リストを管理するデータ構造です。キューやスタック、タイムラインなどの実装に最適です。
3-1. LPUSH / RPUSH - リストへの要素追加
redis# リストの左側(先頭)に追加
LPUSH tasks "タスク3"
# => (integer) 1
LPUSH tasks "タスク2" "タスク1"
# => (integer) 3
# リストの右側(末尾)に追加
RPUSH tasks "タスク4"
# => (integer) 4
LPUSH は先頭に、RPUSH は末尾に要素を追加します。複数の値を一度に追加することも可能です。
3-2. LPOP / RPOP - リストからの要素取り出し
redis# 左側(先頭)から取り出し
LPOP tasks
# => "タスク1"
# 右側(末尾)から取り出し
RPOP tasks
# => "タスク4"
# 複数個を一度に取り出し(Redis 6.2以降)
LPOP tasks 2
# => 1) "タスク2"
# => 2) "タスク3"
LPOP と RPOP は要素を取り出すと同時にリストから削除します。
3-3. LLEN - リストの長さ取得
redis# リストの要素数を取得
RPUSH queue "item1" "item2" "item3"
# => (integer) 3
LLEN queue
# => (integer) 3
3-4. LRANGE - リストの範囲取得
redis# リストの一部を取得(0始まりのインデックス)
LRANGE queue 0 1
# => 1) "item1"
# => 2) "item2"
# 全要素を取得
LRANGE queue 0 -1
# => 1) "item1"
# => 2) "item2"
# => 3) "item3"
# 末尾2件を取得
LRANGE queue -2 -1
# => 1) "item2"
# => 2) "item3"
LRANGE はリストの要素を削除せずに参照します。-1 は末尾を意味します。
3-5. LINDEX - インデックス指定で要素取得
redis# 指定位置の要素を取得
LINDEX queue 0
# => "item1"
LINDEX queue 2
# => "item3"
# 負のインデックスで末尾から指定
LINDEX queue -1
# => "item3"
LINDEX は特定位置の要素を取得します。要素は削除されません。
3-6. LSET - インデックス指定で要素更新
redis# 指定位置の要素を更新
LSET queue 1 "updated_item2"
# => OK
LRANGE queue 0 -1
# => 1) "item1"
# => 2) "updated_item2"
# => 3) "item3"
LSET は既存の要素を上書きします。範囲外のインデックスを指定するとエラーになります。
3-7. LINSERT - 要素の挿入
redis# 特定要素の前後に挿入
LINSERT queue BEFORE "updated_item2" "inserted_before"
# => (integer) 4
LINSERT queue AFTER "updated_item2" "inserted_after"
# => (integer) 5
LRANGE queue 0 -1
# => 1) "item1"
# => 2) "inserted_before"
# => 3) "updated_item2"
# => 4) "inserted_after"
# => 5) "item3"
LINSERT は指定した要素の前後に新しい要素を挿入します。
3-8. LREM - 要素の削除
redis# 指定した値を持つ要素を削除
RPUSH mylist "a" "b" "a" "c" "a"
# => (integer) 5
# 先頭から2個の"a"を削除
LREM mylist 2 "a"
# => (integer) 2
LRANGE mylist 0 -1
# => 1) "b"
# => 2) "c"
# => 3) "a"
# 末尾から1個の"a"を削除(負の数で末尾から)
LREM mylist -1 "a"
# => (integer) 1
# 全ての"b"を削除(0で全て)
LREM mylist 0 "b"
# => (integer) 1
LREM は値を指定して要素を削除します。削除個数を制御できる点が特徴です。
3-9. LTRIM - リストの切り詰め
redis# 指定範囲外の要素を削除
RPUSH timeline "post1" "post2" "post3" "post4" "post5"
# => (integer) 5
# 最初の3件だけ残す
LTRIM timeline 0 2
# => OK
LRANGE timeline 0 -1
# => 1) "post1"
# => 2) "post2"
# => 3) "post3"
LTRIM は指定範囲の要素だけを残し、それ以外を削除します。固定長キューの実装に便利です。
3-10. RPOPLPUSH - リスト間の要素移動
redis# 右側から取り出して別リストの左側に追加
RPUSH source "item1" "item2" "item3"
# => (integer) 3
RPOPLPUSH source destination
# => "item3"
LRANGE source 0 -1
# => 1) "item1"
# => 2) "item2"
LRANGE destination 0 -1
# => 1) "item3"
RPOPLPUSH は、あるリストから要素を取り出して別のリストに移動します。アトミックな操作のため、タスクキューの実装に適しています。
3-11. LMOVE - 柔軟なリスト間移動
redis# より柔軟なリスト間移動(Redis 6.2以降)
LMOVE source destination LEFT RIGHT
# => "item1"(sourceの左端からdestinationの右端へ)
LRANGE source 0 -1
# => 1) "item2"
LRANGE destination 0 -1
# => 1) "item3"
# => 2) "item1"
LMOVE は RPOPLPUSH の上位互換で、取り出しと追加の両側を指定できます。
3-12. BLPOP / BRPOP - ブロッキング取り出し
redis# リストが空の場合、要素が追加されるまで待機
BLPOP waiting_queue 10
# => (nil)(10秒後タイムアウト)
# 別のクライアントからRPUSH waiting_queue "new_item"を実行すると即座に返る
BLPOP waiting_queue 10
# => 1) "waiting_queue"
# => 2) "new_item"
BLPOP と BRPOP は、リストが空の場合に指定秒数だけ待機します。リアルタイムキューの実装に最適です。
3-13. BRPOPLPUSH - ブロッキング付き移動
redis# ブロッキングしながらリスト間移動
BRPOPLPUSH source_queue dest_queue 30
# => "item"(30秒待機、要素があれば即座に移動)
BRPOPLPUSH は RPOPLPUSH のブロッキング版です。信頼性の高いキューシステムに使われます。
3-14. BLMOVE - ブロッキング柔軟移動
redis# ブロッキング付き柔軟移動(Redis 6.2以降)
BLMOVE source_queue dest_queue LEFT RIGHT 30
# => "item"
3-15. LPUSHX / RPUSHX - 存在する場合のみ追加
redis# リストが存在する場合のみ追加
LPUSHX existing_list "new_item"
# => (integer) 0(リストが存在しないため失敗)
RPUSH existing_list "first"
# => (integer) 1
LPUSHX existing_list "second"
# => (integer) 2(成功)
LPUSHX と RPUSHX は、リストが既に存在する場合のみ要素を追加します。
3-16. LPOS - 要素の位置検索
redis# 要素のインデックスを検索(Redis 6.0.6以降)
RPUSH search_list "apple" "banana" "apple" "cherry" "apple"
# => (integer) 5
LPOS search_list "apple"
# => (integer) 0(最初の出現位置)
# 2番目の出現位置を検索
LPOS search_list "apple" RANK 2
# => (integer) 2
# 全ての出現位置を検索
LPOS search_list "apple" COUNT 0
# => 1) (integer) 0
# => 2) (integer) 2
# => 3) (integer) 4
LPOS は特定の値を持つ要素の位置を検索します。
3-17. LMPOP - 複数リストから取り出し
redis# 複数のリストから要素を取り出し(Redis 7.0以降)
RPUSH list1 "a" "b"
RPUSH list2 "c" "d"
# => (integer) 2
LMPOP 2 list1 list2 LEFT COUNT 1
# => 1) "list1"
# => 2) 1) "a"
3-18. BLMPOP - ブロッキング複数リスト取り出し
redis# ブロッキング付き複数リスト取り出し(Redis 7.0以降)
BLMPOP 10 2 list1 list2 LEFT COUNT 2
# => 1) "list1"
# => 2) 1) "b"
3-19. LCS - リスト比較(最長共通部分列)
実際には文字列コマンドですが、リスト的な使い方も可能です。
redis# 2つの文字列の最長共通部分列を取得(Redis 7.0以降)
SET key1 "ohmytext"
SET key2 "mynewtext"
# => OK
LCS key1 key2
# => "mytext"
3-20. List の実践パターン - タイムライン実装
redis# タイムライン機能の実装例
# 新しい投稿を追加
LPUSH user:1000:timeline "post:5001"
# => (integer) 1
# 最新100件のみ保持
LTRIM user:1000:timeline 0 99
# => OK
# 最新10件を取得
LRANGE user:1000:timeline 0 9
# => 1) "post:5001"
# => 2) "post:5000"
# => ...
この組み合わせで、効率的なタイムライン機能が実装できます。
4. Set コマンド(15 本)
Set は重複のない要素の集合を管理します。タグ管理、ユニークユーザーの追跡、集合演算などに適しています。
4-1. SADD - セットへの要素追加
redis# セットに要素を追加(重複は無視される)
SADD tags:article1 "Redis" "NoSQL" "Database"
# => (integer) 3
SADD tags:article1 "Redis"
# => (integer) 0(既に存在するため追加されない)
SADD はセットに要素を追加します。既に存在する要素は追加されません。
4-2. SREM - セットからの要素削除
redis# 要素を削除
SREM tags:article1 "Database"
# => (integer) 1
# 複数要素を同時削除
SREM tags:article1 "Redis" "NoSQL"
# => (integer) 2
4-3. SMEMBERS - 全要素の取得
redis# セットの全要素を取得
SADD fruits "apple" "banana" "orange"
# => (integer) 3
SMEMBERS fruits
# => 1) "orange"
# => 2) "banana"
# => 3) "apple"
# (順序は保証されない)
SMEMBERS はセットの全要素を返します。要素数が多い場合は SSCAN の使用を検討してください。
4-4. SISMEMBER - 要素の存在確認
redis# 要素がセットに含まれるか確認
SISMEMBER fruits "apple"
# => (integer) 1(存在する)
SISMEMBER fruits "grape"
# => (integer) 0(存在しない)
4-5. SMISMEMBER - 複数要素の存在確認
redis# 複数要素の存在を一度に確認(Redis 6.2以降)
SMISMEMBER fruits "apple" "grape" "banana"
# => 1) (integer) 1
# => 2) (integer) 0
# => 3) (integer) 1
4-6. SCARD - セットの要素数
redis# セットのサイズを取得
SCARD fruits
# => (integer) 3
4-7. SPOP - ランダム要素の取り出しと削除
redis# ランダムに要素を取り出して削除
SPOP fruits
# => "banana"(ランダム)
# 複数個をランダム取り出し
SPOP fruits 2
# => 1) "apple"
# => 2) "orange"
SPOP は抽選システムなどで活用できます。要素はセットから削除されます。
4-8. SRANDMEMBER - ランダム要素の取得(削除なし)
redis# ランダム要素を取得(削除しない)
SADD colors "red" "blue" "green" "yellow"
# => (integer) 4
SRANDMEMBER colors
# => "blue"(ランダム)
# 複数個をランダム取得
SRANDMEMBER colors 2
# => 1) "red"
# => 2) "green"
SRANDMEMBER は要素を削除せずにランダム取得します。
4-9. SMOVE - セット間の要素移動
redis# 要素を別のセットに移動
SADD set1 "a" "b" "c"
SADD set2 "x" "y"
# => (integer) 2
SMOVE set1 set2 "b"
# => (integer) 1
SMEMBERS set1
# => 1) "a"
# => 2) "c"
SMEMBERS set2
# => 1) "b"
# => 2) "x"
# => 3) "y"
4-10. SUNION - セットの和集合
redis# 複数セットの和集合を取得
SADD group1 "Alice" "Bob"
SADD group2 "Bob" "Charlie"
# => (integer) 2
SUNION group1 group2
# => 1) "Alice"
# => 2) "Bob"
# => 3) "Charlie"
SUNION は複数のセットを結合した結果を返します。
4-11. SUNIONSTORE - 和集合の保存
redis# 和集合を新しいセットとして保存
SUNIONSTORE all_members group1 group2
# => (integer) 3
SMEMBERS all_members
# => 1) "Alice"
# => 2) "Bob"
# => 3) "Charlie"
4-12. SINTER - セットの積集合
redis# 複数セットの積集合(共通要素)を取得
SINTER group1 group2
# => 1) "Bob"
SINTER は全てのセットに共通する要素を返します。共通の友人検索などに使えます。
4-13. SINTERSTORE - 積集合の保存
redis# 積集合を新しいセットとして保存
SINTERSTORE common_members group1 group2
# => (integer) 1
SMEMBERS common_members
# => 1) "Bob"
4-14. SDIFF - セットの差集合
redis# 差集合を取得(最初のセットから他を除外)
SDIFF group1 group2
# => 1) "Alice"
SDIFF は最初のセットから後続セットの要素を除いた結果を返します。
4-15. SDIFFSTORE - 差集合の保存
redis# 差集合を新しいセットとして保存
SDIFFSTORE unique_to_group1 group1 group2
# => (integer) 1
SMEMBERS unique_to_group1
# => 1) "Alice"
SDIFFSTORE は差集合を永続化します。
5. Sorted Set(ZSet)コマンド(20 本)
Sorted Set は、各要素にスコアが付いた順序付き集合です。ランキング、優先度付きキュー、時系列データなどに最適です。
5-1. ZADD - 要素とスコアの追加
redis# スコア付きで要素を追加
ZADD ranking 100 "player1"
# => (integer) 1
# 複数要素を同時追加
ZADD ranking 85 "player2" 92 "player3" 78 "player4"
# => (integer) 3
# 既存要素のスコア更新
ZADD ranking 95 "player1"
# => (integer) 0(新規追加ではなく更新)
ZADD はスコアと要素のペアを追加します。同じ要素を再度追加するとスコアが更新されます。
5-2. ZRANGE - 範囲取得(スコア昇順)
redis# インデックス範囲で取得(スコア昇順)
ZRANGE ranking 0 2
# => 1) "player4"
# => 2) "player2"
# => 3) "player3"
# スコアも含めて取得
ZRANGE ranking 0 2 WITHSCORES
# => 1) "player4"
# => 2) "78"
# => 3) "player2"
# => 4) "85"
# => 5) "player3"
# => 6) "92"
ZRANGE はスコアの低い順(昇順)で要素を取得します。
5-3. ZREVRANGE - 範囲取得(スコア降順)
redis# スコア降順で取得(ランキング表示に便利)
ZREVRANGE ranking 0 2 WITHSCORES
# => 1) "player1"
# => 2) "95"
# => 3) "player3"
# => 4) "92"
# => 5) "player2"
# => 6) "85"
ZREVRANGE はスコアの高い順(降順)で取得します。トップランキングの表示に使います。
5-4. ZRANGEBYSCORE - スコア範囲で取得
redis# スコア範囲を指定して取得
ZRANGEBYSCORE ranking 80 95
# => 1) "player2"
# => 2) "player3"
# => 3) "player1"
# 無限大を使った範囲指定
ZRANGEBYSCORE ranking -inf 90
# => 1) "player4"
# => 2) "player2"
# 上限件数指定
ZRANGEBYSCORE ranking 0 100 LIMIT 0 2
# => 1) "player4"
# => 2) "player2"
ZRANGEBYSCORE は特定スコア範囲の要素を取得します。時間範囲検索などに便利です。
5-5. ZREVRANGEBYSCORE - スコア範囲で降順取得
redis# スコア範囲を指定して降順取得
ZREVRANGEBYSCORE ranking 95 80
# => 1) "player1"
# => 2) "player3"
# => 3) "player2"
ZREVRANGEBYSCORE は ZRANGEBYSCORE の降順版です。
5-6. ZRANK - 要素の順位取得(昇順)
redis# 要素の順位を取得(0始まり)
ZRANK ranking "player1"
# => (integer) 3(スコア昇順での順位)
ZRANK は要素がスコア昇順で何位かを返します。
5-7. ZREVRANK - 要素の順位取得(降順)
redis# スコア降順での順位を取得
ZREVRANK ranking "player1"
# => (integer) 0(1位)
ZREVRANK ranking "player4"
# => (integer) 3(4位)
ZREVRANK はスコア降順での順位を返します。ランキングシステムでよく使います。
5-8. ZSCORE - 要素のスコア取得
redis# 要素のスコアを取得
ZSCORE ranking "player1"
# => "95"
5-9. ZCARD - 要素数の取得
redis# Sorted Setの要素数を取得
ZCARD ranking
# => (integer) 4
5-10. ZCOUNT - スコア範囲内の要素数
redis# 指定スコア範囲内の要素数を取得
ZCOUNT ranking 80 95
# => (integer) 3
ZCOUNT は特定スコア範囲に含まれる要素数を効率的にカウントします。
5-11. ZINCRBY - スコアの増減
redis# スコアを増加(ゲームのポイント加算など)
ZINCRBY ranking 10 "player4"
# => "88"
# 負の値で減少
ZINCRBY ranking -5 "player2"
# => "80"
ZINCRBY はアトミックにスコアを増減させます。リアルタイムランキングに最適です。
5-12. ZREM - 要素の削除
redis# 要素を削除
ZREM ranking "player4"
# => (integer) 1
# 複数要素を同時削除
ZREM ranking "player2" "player3"
# => (integer) 2
5-13. ZREMRANGEBYRANK - 順位範囲で削除
redis# 順位範囲を指定して削除(下位を削除する場合など)
ZADD scores 100 "a" 200 "b" 300 "c" 400 "d" 500 "e"
# => (integer) 5
# 下位2件を削除
ZREMRANGEBYRANK scores 0 1
# => (integer) 2
ZRANGE scores 0 -1
# => 1) "c"
# => 2) "d"
# => 3) "e"
ZREMRANGEBYRANK は指定順位範囲の要素を削除します。
5-14. ZREMRANGEBYSCORE - スコア範囲で削除
redis# スコア範囲を指定して削除
ZREMRANGEBYSCORE scores 250 350
# => (integer) 1("c"が削除される)
ZRANGE scores 0 -1
# => 1) "d"
# => 2) "e"
5-15. ZPOPMIN / ZPOPMAX - 最小/最大要素の取り出し
redis# 最小スコア要素を取り出して削除
ZADD pqueue 1 "task1" 5 "task2" 3 "task3"
# => (integer) 3
ZPOPMIN pqueue
# => 1) "task1"
# => 2) "1"
# 最大スコア要素を取り出し
ZPOPMAX pqueue
# => 1) "task2"
# => 2) "5"
# 複数個を同時取り出し
ZPOPMIN pqueue 2
# => 1) "task3"
# => 2) "3"
ZPOPMIN と ZPOPMAX は優先度キューの実装に便利です(Redis 5.0 以降)。
5-16. BZPOPMIN / BZPOPMAX - ブロッキング取り出し
redis# 要素があるまで待機してから取り出し
BZPOPMIN priority_queue 10
# => 1) "priority_queue"
# => 2) "task"
# => 3) "priority_score"
# (10秒待機、タイムアウトならnil)
BZPOPMIN と BZPOPMAX は、要素が追加されるまでブロックします(Redis 5.0 以降)。
5-17. ZUNION - 和集合の取得
redis# 複数Sorted Setの和集合を計算(Redis 6.2以降)
ZADD zset1 1 "a" 2 "b"
ZADD zset2 2 "b" 3 "c"
# => (integer) 2
ZUNION 2 zset1 zset2 WITHSCORES
# => 1) "a"
# => 2) "1"
# => 3) "c"
# => 4) "3"
# => 5) "b"
# => 6) "4"(スコアが合算される)
5-18. ZUNIONSTORE - 和集合の保存
redis# 和集合を新しいSorted Setとして保存
ZUNIONSTORE result 2 zset1 zset2
# => (integer) 3
ZRANGE result 0 -1 WITHSCORES
# => 1) "a"
# => 2) "1"
# => 3) "c"
# => 4) "3"
# => 5) "b"
# => 6) "4"
5-19. ZINTER - 積集合の取得
redis# 複数Sorted Setの積集合を計算(Redis 6.2以降)
ZINTER 2 zset1 zset2 WITHSCORES
# => 1) "b"
# => 2) "4"
ZINTER は全てのセットに共通する要素のみを返します。
5-20. ZINTERSTORE - 積集合の保存
redis# 積集合を保存(重みを指定可能)
ZINTERSTORE result 2 zset1 zset2 WEIGHTS 2 1
# => (integer) 1(共通要素"b"のみ)
ZSCORE result "b"
# => "6"(2*2 + 1*2 = 6)
ZINTERSTORE は重み付け計算もサポートしており、複雑なスコア計算に使えます。
6. Stream コマンド(15 本)
Stream は Redis 5.0 で追加されたログ型データ構造です。時系列データ、イベントストリーム、メッセージキューなどに最適です。
6-1. XADD - エントリの追加
redis# Streamにエントリを追加(IDは自動生成)
XADD mystream * sensor_id 1234 temperature 23.5 humidity 65
# => "1704067200000-0"(タイムスタンプベースのID)
# 明示的にIDを指定
XADD mystream 1704067201000-0 sensor_id 1234 temperature 24.0 humidity 66
# => "1704067201000-0"
# 最大長を制限(古いエントリを自動削除)
XADD logs * MAXLEN ~ 1000 level "info" message "System started"
# => "1704067202000-0"
XADD は Stream に新しいエントリを追加します。*
を使うと自動的にユニークな ID が生成されます。
6-2. XRANGE - 範囲取得
redis# ID範囲を指定してエントリを取得
XRANGE mystream - +
# => 1) 1) "1704067200000-0"
# => 2) 1) "sensor_id"
# => 2) "1234"
# => 3) "temperature"
# => 4) "23.5"
# => 5) "humidity"
# => 6) "65"
# => 2) 1) "1704067201000-0"
# => 2) 1) "sensor_id"
# => 2) "1234"
# => 3) "temperature"
# => 4) "24.0"
# => 5) "humidity"
# => 6) "66"
# 件数制限
XRANGE mystream - + COUNT 10
# => (最大10件)
XRANGE は -
で最小 ID、+
で最大 ID を意味します。時系列データの範囲検索に便利です。
6-3. XREVRANGE - 逆順範囲取得
redis# 新しい順(降順)でエントリを取得
XREVRANGE mystream + - COUNT 5
# => (最新5件を降順で)
XREVRANGE は最新データから取得したい場合に使います。
6-4. XLEN - エントリ数の取得
redis# Streamのエントリ数を取得
XLEN mystream
# => (integer) 2
6-5. XREAD - 複数 Stream からの読み取り
redis# 複数Streamから新しいエントリを読み取り
XREAD COUNT 10 STREAMS mystream logs 0-0 0-0
# => 1) 1) "mystream"
# => 2) 1) 1) "1704067200000-0"
# => 2) 1) "sensor_id"
# => 2) "1234"
# => ...
# => 2) 1) "logs"
# => 2) ...
# ブロッキングモード(新しいデータが来るまで待機)
XREAD BLOCK 5000 STREAMS mystream $
# => (5秒間待機、新データがあれば即座に返る)
XREAD は複数の Stream を監視できます。BLOCK
オプションでリアルタイム処理が可能です。
6-6. XGROUP CREATE - コンシューマグループ作成
redis# コンシューマグループを作成(複数クライアントでの分散処理用)
XGROUP CREATE mystream mygroup 0
# => OK
# 最新エントリから開始するグループ
XGROUP CREATE mystream newgroup $
# => OK
コンシューマグループを使うと、複数のクライアントで Stream を分散処理できます。
6-7. XREADGROUP - グループでの読み取り
redis# コンシューマグループ経由でエントリを読み取り
XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS mystream >
# => 1) 1) "mystream"
# => 2) 1) 1) "1704067200000-0"
# => 2) 1) "sensor_id"
# => 2) "1234"
# => ...
XREADGROUP は各エントリが一度だけ配信されることを保証します。
6-8. XACK - エントリの確認応答
redis# エントリの処理完了を通知
XACK mystream mygroup 1704067200000-0
# => (integer) 1
XACK で処理完了を通知することで、エントリが再配信されなくなります。
6-9. XPENDING - 未確認エントリの確認
redis# 未確認(処理中)のエントリを確認
XPENDING mystream mygroup
# => 1) (integer) 0(未確認エントリ数)
# => 2) (nil)(最小ID)
# => 3) (nil)(最大ID)
# => 4) (nil)(コンシューマ別集計)
# 詳細情報を取得
XPENDING mystream mygroup - + 10
# => (未確認エントリの詳細リスト)
XPENDING は処理に失敗したエントリの検出に使います。
6-10. XCLAIM - エントリの所有権移転
redis# 他のコンシューマから処理中のエントリを奪取
XCLAIM mystream mygroup consumer2 3600000 1704067200000-0
# => 1) 1) "1704067200000-0"
# => 2) 1) "sensor_id"
# => 2) "1234"
# => ...
XCLAIM は、処理が止まったエントリを別のコンシューマに再割り当てします。
6-11. XAUTOCLAIM - 自動所有権移転
redis# 一定時間以上処理されていないエントリを自動取得(Redis 6.2以降)
XAUTOCLAIM mystream mygroup consumer2 3600000 0-0 COUNT 10
# => 1) "0-0"(次のカーソル)
# => 2) 1) 1) "1704067200000-0"
# => 2) 1) "sensor_id"
# => 2) "1234"
# => ...
XAUTOCLAIM は XCLAIM を自動化したもので、より簡単に使えます。
6-12. XINFO STREAM - Stream 情報の取得
redis# Streamの詳細情報を取得
XINFO STREAM mystream
# => 1) "length"
# => 2) (integer) 2
# => 3) "radix-tree-keys"
# => 4) (integer) 1
# => 5) "radix-tree-nodes"
# => 6) (integer) 2
# => 7) "groups"
# => 8) (integer) 2
# => 9) "last-generated-id"
# => 10) "1704067201000-0"
# => 11) "first-entry"
# => ...
# => 12) "last-entry"
# => ...
6-13. XINFO GROUPS - グループ情報の取得
redis# コンシューマグループの情報を取得
XINFO GROUPS mystream
# => 1) 1) "name"
# => 2) "mygroup"
# => 3) "consumers"
# => 4) (integer) 1
# => 5) "pending"
# => 6) (integer) 0
# => 7) "last-delivered-id"
# => 8) "1704067200000-0"
6-14. XDEL - エントリの削除
redis# 特定のエントリを削除
XDEL mystream 1704067200000-0
# => (integer) 1
XDEL は不要なエントリを削除します。ただし、Stream の主な用途はログ保存のため、通常は MAXLEN で自動削除を使います。
6-15. XTRIM - Stream の切り詰め
redis# 古いエントリを削除してサイズを制限
XTRIM mystream MAXLEN 1000
# => (integer) 0(削除されたエントリ数)
# 近似的な切り詰め(パフォーマンス優先)
XTRIM mystream MAXLEN ~ 1000
# => (integer) 0
XTRIM は Stream のサイズを制御します。~
を使うと効率的な削除が可能です。
まとめ
Redis の 6 つの主要データ構造と 100 個のコマンドを体系的に見てきました。最後に、各データ構造の特徴と用途を整理しておきましょう。
# | データ構造 | 主な用途 | 代表コマンド | 特徴 |
---|---|---|---|---|
1 | String/Key | セッション、カウンター、キャッシュ | SET, GET, INCR | 最もシンプル、高速 |
2 | Hash | ユーザー情報、設定データ | HSET, HGET, HINCRBY | 構造化データに最適 |
3 | List | タイムライン、キュー、スタック | LPUSH, RPUSH, BLPOP | 順序保持、両端操作が高速 |
4 | Set | タグ、ユニークユーザー | SADD, SINTER, SUNION | 重複排除、集合演算 |
5 | Sorted Set | ランキング、優先度キュー | ZADD, ZRANGE, ZINCRBY | スコア付き、範囲検索が高速 |
6 | Stream | イベントログ、メッセージング | XADD, XREAD, XREADGROUP | 時系列データ、分散処理 |
学習を継続するために
この記事で紹介した 100 個のコマンドは、実務で頻繁に使用される重要なものばかりです。全てを一度に覚える必要はありません。まずは以下の順序で学習することをおすすめします。
ステップ 1:基礎コマンドの習得
- String の基本操作(SET, GET, INCR)
- Hash の基本操作(HSET, HGET, HGETALL)
- List の基本操作(LPUSH, RPUSH, LRANGE)
ステップ 2:データ構造の使い分け
- Set と Sorted Set の違いを理解
- List と Stream の違いを理解
- 実際のユースケースで適切な構造を選択
ステップ 3:高度な機能の活用
- ブロッキングコマンド(BLPOP, BRPOP)
- Pub/Sub 機能との組み合わせ
- トランザクション(MULTI, EXEC)
実践での活用方法
コマンドを学んだら、実際のアプリケーションで活用してみましょう。以下のような機能を実装することで、理解が深まります。
- ランキングシステム:Sorted Set で実装
- リアルタイムチャット:List または Stream で実装
- セッション管理:Hash または String で実装
- タグ検索:Set の集合演算で実装
- キュー処理:List のブロッキングコマンドで実装
Redis は高速で柔軟なデータストアとして、多くのプロダクションシステムで活用されています。この記事が、皆さんの Redis 学習の一助となれば幸いです。
実際に手を動かしながら、一つずつコマンドを試してみてください。そうすることで、Redis の真の力を実感できるはずです。
関連リンク
- article
Redis コマンド 100 本ノック:Key/Hash/List/Set/ZSet/Stream 早見表
- article
Redis セットアップ完全版(macOS/Homebrew):設定テンプレ付き最短構築
- article
Redis vs Memcached 徹底比較:スループット・メモリ効率・機能差の実測
- article
Redis OOM を根絶:maxmemory・eviction・大キー検出の実践トリアージ
- article
Redis 基礎 速習:データ構造と単一スレッドの仕組みを図解で理解
- article
Convex で実践する CQRS/イベントソーシング:履歴・再生・集約の設計ガイド
- article
LangChain と LlamaIndex の設計比較:API 哲学・RAG 構成・運用コストを検証
- article
Jotai が再レンダリング地獄に?依存グラフの暴走を止める診断手順
- article
成果が出る GPT-5-Codex 導入ロードマップ:評価指標(ROI/品質/速度)と失敗しない運用フロー
- article
Jest expect.extend チートシート:実務で使えるカスタムマッチャー 40 連発
- article
Astro の View Transitions 徹底解説:SPA 並みの滑らかなページ遷移を実装するコツ
- blog
iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
- blog
Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
- blog
【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
- blog
Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
- blog
Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
- blog
フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来