私はUserクラスを持つアプリケーションエンジンプロジェクト(java)を持っています。私は安価な友人関係システムをモデル化したいと思います。各ユーザーは最大50人の友達を持つことができます。友人関係をモデリングする安価な方法
「友人」は、ユーザーが持つ友人であるユーザ名のカンマ区切りのリストであるclass User {
String username;
Text friends; // "joe,mary,frank,pete"
}
:私のようなおどけた何かをすることを考えています。ここで私がサポートしたい操作していると私は上記でそれらを行うだろうか:
は私の完全な友達リスト取得
だけで、ユーザーオブジェクトを検索カンマ区切りのリストをバック返します友人の
、ターゲット名が文字列に存在する場合でない場合は、チェックし、自分のユーザーオブジェクトを取得友人
を追加します。最後に追加します。変更されたユーザーオブジェクトをデータストアに保存し直します。
それは、文字列からそれを削除しない場合は、私のユーザーオブジェクトを取得するターゲット名が文字列に存在するかどうかをチェック友人に
を削除します。変更されたユーザーオブジェクトをデータストアに保存し直します。
共通の友人
は、ユーザ名が互いのユーザーオブジェクトに表示されていることを確認し、両方のユーザーオブジェクトを取得する2人のユーザーです。
おそらくユーザーが友人のリストを参照する必要があるときに、データストアから各エンティティをフェッチする(友人の完全なリストは、自分のアプリケーションのためにかなり重要であり、別のエンティティとして各関係を格納することは私には悪夢のようでしまうの取得私を破産する)。私はText属性からの単純な読み込みがはるかに軽いことを望んでいます。
ここでの最大の欠点は、友人のシナリオを確認することですが、頻繁に起こることはありません。データストアから2つのユーザーオブジェクトを取得して文字列の比較を行うのが性能面で悲惨なものになるかどうかはわかりません。大丈夫でしょうか?データストアからのオブジェクトの作成と削除は、既存のオブジェクトを変更するだけでは済まされないということも読んでいると思います。だから、友人操作の追加/削除はこのように良いかもしれません。
これ以上の最適な方法についてご意見をお寄せいただければ幸いです。
は-------------
--------------------------更新をありがとう--------エイドリアンさんのコメントを1として
を、私はまた、次の手順を実行できます。
class User {
String username;
List<String> friends;
// or //
Set<String> friends;
}
をだから私は、私はリストを使用している場合、これらのエンティティは、デフォルトでインデックスを取得すると思います。私はGQLクエリを実行できるかどうかはわかりませんが、実際にはどのエンティティもフェッチせずに一致を得るためにリストがインデックスされていることを知っています。ような何か:余分な時間がときからフェッチそれらをデシリアライズするために注意しなければならない、
セットとして保存SELECT COUNT FROM User WHERE
(username = "me" && friends = "bob") &&
(username = "bob" && friends = "me")
は、私は両方のユーザーオブジェクトをロードした場合より高速な検索を行うに役立つだろうが、私はリストとセットの両方のためだと思いますデータストアでは、そのメリットが否定されているかどうかはわかりません。多分それが助けてくれる以上に傷つけるだろうか?
は実際のリストを友人に使用できます。またはHashMap の方が優れているので、平均O(1)を検索して友人リストの交差操作を改善できます。最大50人の友人がいることを考えれば、あなたが選んだデザインに関係なく、パフォーマンスの問題にぶつかるのではないでしょうか。 –
Adrian
良い点、私はそのオプションで質問を更新しました。私は、データストアを読み書きするときに、ListオブジェクトまたはSetオブジェクトへの直列化にいくらかのペナルティがあると思います。私はリストを使用している場合、それを完全に避けるためにクエリを使用できるかどうかはわかりません。それはクールだ。ありがとうございます – user291701
長い文字列の方法で行く必要がある場合は、プレフィックスツリーを使用して一般的な友人を見つけるスピードアップできます。問題は、文字列Bの文字列Aの部分文字列を見つけることになります。 – Adrian