2012-02-16 13 views
7

私は客観化することはかなり新しいです、と私は何かをする 最善の方法について簡単な質問があった:(のための電子メールを考える関係を客観化する:1対多、これを効率的に行うことはできますか?

は、私は人々が メッセージを送受信することを可能にするアプリケーションを考えてみましょうシンプルさ)。私のアプリケーションが読み込まれたときに、私は は、 は、特定のユーザーにメッセージを送信したすべての連絡先からすべての単一のメッセージを読み込みたい。それは無駄でしょう。 代わりに、ユーザに というメッセージがある連絡先をすべて読み込み(読み込みまたは未読)、 のアプリに連絡先のリストを表示できるようにしたい場合、ユーザーが特定の連絡先をクリックすると、その連絡先からのメッセージのすべて をロードしてユーザーに表示します。

私は、アカウントのすべてのメッセージを読み込まないと、これを行う良い方法が見つかりません。 多対1の関係でObjectify wikiを読みましたが、それでもなお非常に非効率的ではない というのは良い方法です。オブジェクト化サイトでは、特定のユーザーのすべてのメッセージをロードしてから、固有の連絡先を解析する必要があるような方法が考えられます。私は、わずかApp Engineは読み込み、できるだけ書き込み、と私はスモールズを使用しようとしている可能 の代わりに読み込み場所( への全体的なコストは、私のアプリを実行して使用しようとしている

は私の中の大きな関心事であります私はこれを作っている)。

Objectifyでは、どうすればよいですか?

答えて

11

これは客観-のAppEngineのGoogleのグループに私の応答からコピーされます。https://groups.google.com/forum/?fromgroups#!topic/objectify-appengine/LlOyRJZRbnk

あなたが記述するもののような「集計データ」を扱うとき三つの主要なオプションがあります。

1)それが必要なときに計算してください

これはあまりにも高価だと私は思っています。

2)バッチ毎にそれを計算し、それが遅延を伴うので

非常に満足しないこの結果を格納します。さらに、毎晩あなたのデータベース全体を調べる必要もありません。

3)データが

このアプローチを変更したときに凝集を更新するには、データ変更もう少し作業を毎回必要とするが、それはほぼ確実にあなたが何をしたいのです。

各ユーザーの連絡先のコレクションを作成します。メッセージが到着したら、その受信者の送信者の連絡先が存在することを確認します。また、受信者が送信者から最後のメッセージを削除したときに連絡先を削除したい場合もあります。

エンティティグループのトランザクションレート制限(1秒あたり1回の書き込み)にぶつからないように注意してください。あなたは、各受信者に連絡先のリストを格納することができ

1):私はいくつかのオプションを順を追ってます

class Person { 
    @Id Long id; 
    Set<Key<Person>> contacts; 
} 

これは個別の問題だろうと言う、受信者が新しい20からメールを受け取った場合など一度にすべての人々。これはほぼ確実に悪い考えです。一方、あなたの連絡先が誰であるかを調べることは驚くほど速くて効率的です。マイナーな改善は、あなたが常にそのデータをロードしないように、人が親に別のエンティティにこれを移動するには、次のようになります。

もちろん
class Contacts { 
    @Parent Key<Person> owner; 
    @Id long id = 1; // there's only ever one of these per person, and it should have a predictable key for fetching 
    Set<Key<Person>> contacts; 
} 

、単一のエンティティのSetは、あなたに50,000エントリの制限を与えます。最初に1Mエンティティのサイズ制限に達した場合は、これよりわずかに小さいかもしれません。あなたのキーが〜20文字の場合、それはほぼ同じです。これが問題の場合は、複数の連絡先エンティティを許可することができます。その時点で、Brett Slatkinの2009 Google I/OトークのRelation Index Entityパターンのようなものがあります。http://www.youtube.com/watch?v=AgaL6NGpkB8

2)連絡先リストあなたは、単純なGET・バイ・キー、キーのみのクエリをする必要はありません - 他の方向

class Person { 
    @Id Long id; 
    @Index Set<Key<Peson>> contactOf; 
} 

にこれはあなたの連絡先が誰であるかを見つけるために、それは少し高価になります。しかし、エンティティの書き込み速度によって実際に制限されるわけではありません。おそらく1秒間に1つ以上のメッセージを送信する人はいないでしょう.1000件のメッセージを一括して送信すると、contactOfを1回のトランザクションで更新できます。

class Contact { 
    @Parent Key<Person> person; 
    @Id Long id; 
    @Index Key<Person> owner; 
} 

これは本当にあります。また、完全に別のエンティティにこれらの連絡先を格納することができ

class Contacts { 
    @Parent Key<Person> person; 
    @Id long id = 1; // there's only ever one of these per person, and it should have a predictable key for fetching 
    Set<Key<Person>> of; 
} 

3):

は、上記のように、あなたはおそらく別のエンティティにこのインデックスを移動したいですソリューション#2の空間効率の低い方法です。

重要なことは、すべてのメッセージの送受信時にこの構造を更新し続けることです。

+0

包括的な回答をいただきありがとうございます。私はgoogle-appengine-groupに関するいくつかのフォローアップの質問をしています。 – spierce7

+0

50,000ではなく5,000の制限で、おそらくタイプミスです。 – gswierczynski

関連する問題