0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Redisの基本: 一般的なデータ型とベストプラクティス

Posted at

表紙

Redis の一般的なデータ型

文字列(Strings)

Redis の文字列は基本的なデータ型であり、文字列値を保存および取得するために使用されます。

  • ユースケース:テキストや数値の保存に適しており、例えばユーザーの名前、メールアドレス、ページカウンターなどに利用できます。また、バイナリデータの保存も可能なため、画像やシリアライズされたオブジェクトの格納にも使えます。
  • メリット:操作が簡単で、インクリメント(INCR)などの原子操作を実行できます。
// 文字列を保存
let _: () = conn.set("username", "alice").await.unwrap();

// 文字列を取得
let username: String = conn.get("username").await.unwrap();

リスト(Lists)

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();

セット(Sets)

セットは、重複のない文字列の無秩序な集合です。

  • ユースケース:タグ、アクセスした IP アドレス、ソーシャルネットワークの友達リストなど、順序を必要としない一意な要素の保存に使用されます。
  • メリット:要素の追加、削除、存在チェックを高速に行え、さらに集合演算(和集合、積集合、差集合)を実行できます。
// セットに要素を追加
let _: () = conn.sadd("tags", "redis").await.unwrap();
let _: () = conn.sadd("tags", "database").await.unwrap();

// セットの全メンバーを取得
let tags: Vec<String> = conn.smembers("tags").await.unwrap();

ソート済みセット(Sorted Sets)

ソート済みセットは、セットに似ていますが、各メンバーにスコア(数値)が関連付けられます。

  • ユースケース:ランキング、優先度キュー、スコア付きのデータの保存に適しています。
  • メリット:セットの基本操作に加え、スコアや辞書順による要素の取得や範囲検索が可能です。
// ソート済みセットに要素を追加
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();

ハッシュ(Hashes)

ハッシュはキーと値のペアの集合であり、プログラミング言語の辞書やオブジェクトに似ています。

  • ユースケース:ユーザー情報(名前、年齢、メールアドレスなど)の保存など、複数の関連データをまとめて管理するのに適しています。
  • メリット:複数のフィールドを一度に読み書きでき、オブジェクトの表現やデータの集約に便利です。
// ハッシュにキーと値を追加
let _: () = conn.hset("user:100", "email", "alice@example.com").await.unwrap();

// ハッシュのすべてのキーと値を取得
let user_info: HashMap<String, String> = conn.hgetall("user:100").await.unwrap();

ビットマップ(Bitmaps)

ビットマップは、ビット単位で構成された配列で、各ビットは独立して設定または取得が可能です。

  • ユースケース:ユーザーの出席状況、特定機能のオン/オフ状態など、存在の有無をマークする場面に適しています。
  • メリット:非常に高い空間効率を持ち、大量のブール値データを扱うのに適しています。
// ビットマップでビットを設定
let _: () = conn.setbit("features", 0, true).await.unwrap();  // 機能0を有効にする

// ビットマップからビット値を取得
let feature_enabled: bool = conn.getbit("features", 0).await.unwrap();

ハイパーログログ(HyperLogLogs)

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 データ型の例です。

ユーザーセッション(User Sessions)

  • 推奨データ型:ハッシュ(Hash)
  • 理由:ハッシュは、ユーザー ID、トークン、最終アクセス日時など、セッションオブジェクトの複数の属性を格納でき、特定のフィールドを個別に更新または取得できます。
let _: () = conn.hset("session:userid", "token", "abc123").await.unwrap();
let _: () = conn.hset("session:userid", "last_access", "2023-01-01").await.unwrap();

リアルタイムメッセージングまたはイベントキューイング(Real-time Messaging or Event Queuing)

  • 推奨データ型:リスト(List)
  • 理由:リストは FIFO キューとして動作し、リアルタイムのメッセージ処理やタスクキューに適しています。
let _: () = conn.rpush("events_queue", "event1").await.unwrap();
let event: String = conn.lpop("events_queue").await.unwrap();

アクセスカウンターまたはレート制限(Access Counters or Rate Limiting)

  • 推奨データ型:文字列(String)
  • 理由:文字列型は原子操作によるインクリメントをサポートし、カウンターとしての使用に適しています。
let _: () = conn.incr("page_view_count", 1).await.unwrap();
let count: i64 = conn.get("page_view_count").await.unwrap();

ランキングまたはスコアソーティング(Leaderboards or Score Sorting)

  • 推奨データ型:ソート済みセット(Sorted Set)
  • 理由:スコアによる自動ソートが可能で、ランキングなどスコア順のデータに最適です。
let _: () = conn.zadd("leaderboard", "user123", 2500).await.unwrap();
let leaderboard: Vec<(String, f64)> = conn.zrange_withscores("leaderboard", 0, -1).await.unwrap();

ユニーク値のコレクション(タグやカテゴリなど)(Unique Value Collections like Tags or Categories)

  • 推奨データ型:セット(Set)
  • 理由:重複のないデータの保存に適しており、タグの管理などに便利です。
let _: () = conn.sadd("tags", "redis").await.unwrap();
let tags: Vec<String> = conn.smembers("tags").await.unwrap();

複数属性のオブジェクト保存(Multi-attribute Object Storage)

  • 推奨データ型:ハッシュ(Hash)
  • 理由:複数の属性を個別に管理でき、オブジェクトの保存に便利です。
let _: () = conn.hset("user:100", "name", "Alice").await.unwrap();
let user: HashMap<String, String> = conn.hgetall("user:100").await.unwrap();

機能フラグまたはトグル(Feature Flags or Toggles)

  • 推奨データ型:ビットマップ(Bitmap)
  • 理由:機能のオン/オフなど、ブール値の保存に適しています。
let _: () = conn.setbit("features", 1, true).await.unwrap();
let feature_on: bool = conn.getbit("features", 1).await.unwrap();

最適なデータ型の選択は、具体的なニーズに依存します。単純なキーと値のペアであれば文字列型が適していますが、ユーザープロファイルやセッション情報のように複数のフィールドを持つ場合はハッシュ型が便利です。ランキングやスコア順のデータ管理が必要であれば、ソート済みセットが最適です。

それぞれのユースケースに応じた最適なデータ型を選択し、効率的なデータ管理を行いましょう。


私たちはLeapcell、バックエンド・プロジェクトのホスティングの最適解です、組み込みのサーバーレスRedisを搭載しています。

Leapcell

Leapcellは、Webホスティング、非同期タスク、Redis向けの次世代サーバーレスプラットフォームです:

複数言語サポート

  • Node.js、Python、Go、Rustで開発できます。

無制限のプロジェクトデプロイ

  • 使用量に応じて料金を支払い、リクエストがなければ料金は発生しません。

比類のないコスト効率

  • 使用量に応じた支払い、アイドル時間は課金されません。
  • 例: $25で6.94Mリクエスト、平均応答時間60ms。

洗練された開発者体験

  • 直感的なUIで簡単に設定できます。
  • 完全自動化されたCI/CDパイプラインとGitOps統合。
  • 実行可能なインサイトのためのリアルタイムのメトリクスとログ。

簡単なスケーラビリティと高パフォーマンス

  • 高い同時実行性を容易に処理するためのオートスケーリング。
  • ゼロ運用オーバーヘッド — 構築に集中できます。

ドキュメントで詳細を確認!

Try Leapcell

Xでフォローする:@LeapcellHQ


ブログでこの記事を読む

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?