web-dev-qa-db-ja.com

redisのパフォーマンス、jsonオブジェクトを文字列として保存

次のようなユーザーモデルを保存する必要があります。

{ "nickname": "alan",
  "email": ...,
  "password":...,
  ...} // and a couple of other fields

今日、私はセットを使用します:ユーザー
このセットには、user:alanのようなメンバーがいます。
このメンバーには上記のハッシュがあります

これは正常に機能していますが、上記のアプローチの代わりに次のアプローチを使用するのが理にかなっているのではないかと思っていました。

引き続きusersSetを使用します(ユーザー(メンバー)リストを簡単に取得するため)
このセットでは、次のようなキー/値ストレージのみを使用します。

キー:alan値:上記のユーザーハッシュの文字列化バージョン

そうすれば、レコードの取得が簡単になります(JSONでレコードを解析する必要があります)。

私はredisを初めて使用するので、何が最善かわかりません。どう思いますか ?

23
Luc

Redis hashes データ構造を使用して、JSONオブジェクトのフィールドと値を格納できます。たとえば、「users」セットはすべてのユーザーを格納するリストとして引き続き使用でき、個々のJSONオブジェクトは次のようにハッシュに格納できます。

db.hmset("user:id", JSON.stringify(jsonObj));

これで、すべてのユーザーまたは特定のユーザーのみをキーで取得できます(ここから、指定したフィールド/値のみを取得/設定します)。また、 これら2 質問はおそらくあなたのシナリオに関連しています。

編集:(申し訳ありませんが、これについて以前に話したことに気づいていませんでした)

そうすれば、レコードの取得が簡単になります(JSONでレコードを解析する必要があります)。

これは真実ですが、ハッシュデータ構造を使用すると、操作する必要のあるフィールド/値のみを取得/設定できます。オブジェクトの一部のみを変更したい場合(他のことは、毎回オブジェクトを文字列化/解析する必要があることです)、JSONオブジェクト全体を取得すると、パフォーマンスが低下する可能性があります(実行頻度によって異なります)。

20
yojimbo87

ハッシュに対するJSONのもう1つのメリットは、型を維持することです。 _123.3_は文字列_"123.3"_になり、ライブラリによってはNull/Noneが誤って_"null"_にキャストされる可能性があります。

文字列を抽出して期待される型に戻すためのトランスフォーマーを作成する必要があるため、どちらも少し面倒です。

スペース/メモリ消費の考慮事項として、値だけをJSONリスト_["my_type_version", 123.5, null , ... ]_として格納することに傾倒し始めたため、N * ( sum(len(concat(JSON key names)))のオーバーヘッドはありませんでした(私の場合は+ 60%) Redisの使用済みメモリフットプリント。

7
David

覚えておいてください:ハッシュはネストされたオブジェクトを保存できません、JSONはそれを行うことができます。

4
mzalazar

正直なところ、どちらの方法でも問題なく動作します。それを保存する方法は、あなたがする必要がある設計上の決定です。ユーザー情報の取得方法などによって異なります。

パフォーマンスの観点から、ユーザーオブジェクトのJSONエンコードバージョンを保存すると、使用するメモリが少なくなり、保存/取得にかかる時間が短くなります。つまり、JSON解析は、Redisから各フィールドを取得するよりもおそらく高速です。そして、そうでない場合でも、おそらくよりメモリ効率が高くなります。とにかく、パフォーマンスの違いはおそらく最小限です。

3
BMiner