Redis のデータ型を説明しよう: 時期とその使用方法
Daniel Hayes
Full-Stack Engineer · Leapcell

一般的な Redis データ型
文字列
Redis の文字列は、文字列値を格納および取得するために使用される基本的なデータ型です。
- ユースケース: ユーザー名、メールアドレス、ページカウンターなど、テキストまたは数値を格納するのに適しています。文字列はバイナリデータも格納できるため、画像やシリアル化されたオブジェクトを保存するのに最適です。
- 利点: インクリメント(INCR)などのアトミックアクションによる簡単な操作。
// 文字列を保存する let _: () = conn.set("username", "alice").await.unwrap(); // 文字列を取得する let username: String = conn.get("username").await.unwrap();
リスト
Redis リストは、挿入順にソートされた文字列のコレクションです。
- ユースケース: メッセージキュー、アクティビティログ、または最近アクセスされた項目のリストを実装するのに最適です。リストは両端からの要素の追加または削除をサポートし、スタックまたはキューとして使用できます。
- 利点: 高速な挿入および削除操作。FIFO(先入れ先出し)キューまたは LIFO(後入れ先出し)スタックに適しています。
// リストの先頭に要素を追加する let _: () = conn.lpush("events", "login").await.unwrap(); let _: () = conn.lpush("events", "logout").await.unwrap(); // リスト要素を取得する let events: Vec<String> = conn.lrange("events", 0, -1).await.unwrap();
セット
セットは、順序付けられていない一意の文字列のコレクションです。
- ユースケース: タグ、アクセスされた IP アドレス、ソーシャルネットワークの友達リストなど、特定の順序ではなく一意の要素を格納するのに最適です。
- 利点: 要素の追加、削除、および存在の確認のための高速な操作。和集合、積集合、差集合などの集合演算をサポートします。
// セットに要素を追加する let _: () = conn.sadd("tags", "redis").await.unwrap(); let _: () = conn.sadd("tags", "database").await.unwrap(); // すべてのセットメンバーを取得する let tags: Vec<String> = conn.smembers("tags").await.unwrap();
ソートされたセット
ソートされたセットはセットに似ていますが、各メンバーにスコアを関連付けます。
- ユースケース: リーダーボード、優先度キュー、または重み付けされたソートによるデータなど、スコアでソートする必要があるデータを格納するのに適しています。
- 利点: 基本的なセット操作に加えて、スコアまたは辞書順で要素を取得し、特定範囲内の要素を取得することをサポートします。
// ソートされたセットに要素を追加する let _: () = conn.zadd("leaderboard", "alice", 100).await.unwrap(); let _: () = conn.zadd("leaderboard", "bob", 200).await.unwrap(); // ソートされたセット要素を取得する let leaderboard: Vec<(String, f64)> = conn.zrange_withscores("leaderboard", 0, -1).await.unwrap();
ハッシュ
ハッシュは、プログラミング言語の辞書またはオブジェクトに似た、キーと値のペアのコレクションです。
- ユースケース: ユーザー属性(名前、年齢、メールなど)など、オブジェクトまたは複数の関連するデータポイントを格納するのに最適です。
- 利点: 複数のフィールドを一度に読み書きするのに効率的で、オブジェクトの表現やデータポイントの集約に適しています。
// ハッシュにキーと値のペアを追加する let _: () = conn.hset("user:100", "email", "alice@example.com").await.unwrap(); // ハッシュからすべてのキーと値のペアを取得する let user_info: HashMap<String, String> = conn.hgetall("user:100").await.unwrap();
ビットマップ
ビットマップは、各ビットを個別に設定またはクエリできるビットの配列です。
- ユースケース: ユーザーサインインや機能ステータスの切り替えなど、存在をマークする必要があるシナリオに最適です。
- 利点: 大量のブール値を処理するための非常に省スペース。
// ビットマップにビットを設定する let _: () = conn.setbit("features", 0, true).await.unwrap(); // 機能0を有効にする // ビットの値を取得する let feature_enabled: bool = conn.getbit("features", 0).await.unwrap();
HyperLogLog
HyperLogLog は、カーディナリティ(一意の要素の数)を効率的に推定するために使用される確率的データ構造です。
- ユースケース: ウェブサイトの一意の訪問者数など、大規模なデータセットで一意の数を推定するのに最適です。
- 利点: 特に大規模なデータセットを処理する場合、従来のカウント方法と比較して非常にメモリ効率が高い。
// HyperLogLog に要素を追加する let _: () = conn.pfadd("pageviews", "user1").await.unwrap(); let _: () = conn.pfadd("pageviews", "user2").await.unwrap(); // おおよそのカーディナリティを取得する let unique_pageviews: i64 = conn.pfcount("pageviews").await.unwrap();
データ型の選択
バックエンド操作に適した Redis データ型を選択することは、最適なストレージと取得効率を達成するために重要です。データ構造とユースケースを理解することが重要です。以下は、推奨される Redis データ型を使用した一般的なバックエンドシナリオです。
ユーザーセッション
- 推奨タイプ: ハッシュ
- 理由: ハッシュは、ユーザーセッションオブジェクトの複数のプロパティ(ユーザー ID、トークン、最終アクセス時間など)を格納でき、個別の更新または取得が可能です。
let _: () = conn.hset("session:userid", "token", "abc123").await.unwrap(); let _: () = conn.hset("session:userid", "last_access", "2023-01-01").await.unwrap();
リアルタイムメッセージングまたはイベントキューイング
- 推奨タイプ: リスト
- 理由: リストは FIFO キューの特性を提供し、リアルタイムメッセージングまたはタスクキューに適しています。
let _: () = conn.rpush("events_queue", "event1").await.unwrap(); let event: String = conn.lpop("events_queue").await.unwrap();
アクセスカウンターまたはレート制限
- 推奨タイプ: 文字列
- 理由: 文字列はアトミックなインクリメント操作をサポートしており、カウンターに最適です。
let _: () = conn.incr("page_view_count", 1).await.unwrap(); let count: i64 = conn.get("page_view_count").await.unwrap();
リーダーボードまたはスコアソート
- 推奨タイプ: ソートされたセット
- 理由: ソートされたセットは、スコアに基づいてデータを自動的にソートするため、リーダーボードまたはソートされたデータに最適です。
let _: () = conn.zadd("leaderboard", "user123", 2500).await.unwrap(); let leaderboard: Vec<(String, f64)> = conn.zrange_withscores("leaderboard", 0, -1).await.unwrap();
タグやカテゴリのようなユニークな値のコレクション
- 推奨タイプ: セット
- 理由: セットはユニークな値のストレージを提供し、重複排除のシナリオに適しています。
let _: () = conn.sadd("tags", "redis").await.unwrap(); let tags: Vec<String> = conn.smembers("tags").await.unwrap();
複数属性のオブジェクトストレージ
- 推奨タイプ: ハッシュ
- 理由: ハッシュはオブジェクトの複数のフィールドを格納でき、独立したアクセスまたは更新が可能です。
let _: () = conn.hset("user:100", "name", "Alice").await.unwrap(); let user: HashMap<String, String> = conn.hgetall("user:100").await.unwrap();
機能フラグまたはトグル
- 推奨タイプ: ビットマップ
- 理由: ビットマップは、機能トグルのようなブール状態を格納するのに最適です。
let _: () = conn.setbit("features", 1, true).await.unwrap(); let feature_on: bool = conn.getbit("features", 1).await.unwrap();
結論
適切なタイプを選択するかどうかは、特定のニーズによって異なります。データ構造が単純な場合(単一のキーと値のペアなど)、文字列で十分な場合があります。ユーザープロファイルやセッション情報などのより複雑な構造の場合、ハッシュの方が適している場合があります。アプリケーションにリーダーボードまたはソートされたデータが含まれる場合は、それに応じてソートされたセットを使用します。
Leapcell は、サーバーレスRedisが組み込まれた、バックエンドプロジェクトをホストするためのトップチョイスです。
Leapcell は、Webホスティング、非同期タスク、およびRedisの次世代サーバーレスプラットフォームです。
多言語サポート
- Node.js、Python、Go、または Rust で開発します。
無制限のプロジェクトを無料でデプロイ
- 使用量に対してのみ料金を支払います — リクエストもチャージもありません。
比類なき費用対効果
- アイドルチャージなしの従量課金制。
- 例:25ドルで平均応答時間60msで694万リクエストをサポートします。
合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOps統合。
- 実用的な洞察のためのリアルタイムのメトリクスとロギング。
容易なスケーラビリティと高性能
- 高い同時実行性を容易に処理するための自動スケーリング。
- 運用上のオーバーヘッドゼロ — 構築に集中するだけです。
詳細については、ドキュメントをご覧ください。
X でフォローしてください: @LeapcellHQ