2011-08-11 8 views
6

多対多リレーションシップの2つのモデル、TransactionとPersonがあります。各取引には人が含まれています。それぞれの人物には、その人物が接続されている各トランザクションに接続されている金額もあります。そのためには、関係データを使って多対多の関係をモデル化する必要があります。 Googleはこのアプローチをお勧め:この方法でGoogle App Engineのリレーションデータを使用した多対多のモデリング

http://code.google.com/intl/sv-SE/appengine/articles/modeling.html

を私はこのようなモデルがあります:

class TransactionPerson(db.Model): 
    # References 
    transaction = db.ReferenceProperty(Transaction, required=True) 
    person = db.ReferenceProperty(Person, required=True) 
    # Values 
    amount = db.FloatProperty(required=True) 

をしかし、私はそれぞれの人のための量を要約する必要がある場合ので、私はパフォーマンスのためには、非常に悪い見つけますすべてのトランザクションで、金額を合計しながら「結合」を実装するために、Person * Transaction * TransactionPerson回をループする必要があります。

MY IDEA

私の考えでは、トランザクションモデルに二つのリストを持つことです。私は、関連を見つけるために、それぞれの人のためのすべてのTransactionPersonをループする必要はありません

class Transaction(db.Model): 
    persons = ListProperty(db.Key) 
    persons_amount = ListProperty(float) 

この方法トランザクション。また、私は依然として人に基づいてトランザクションを照会することができます。

質問

  1. これは可能ですか?リスト間でインデックスが同期するように、格納/検索時にリストの順序が常に同じであると信じることはできますか?
  2. これは関連するデータと多対多の関係を実装する良い方法ですか?

答えて

2

あなたは間違った問題を解決していると思います。中間の関連エンティティは良いアプローチです。あなたが持っている問題は、要約が計算に時間がかかることです。あなたはそれについてもっと気にする必要があります。

好ましい方法は、の前に要約データを計算することです()。

「1人あたりの取引総額」という特定のケースでは、追加のフィールドをPersonモデルに追加し、すべてのトランザクションの実行中の合計で更新することを意味します。要約値が常に正しいように、TransactionPersonが変更されるたびにこれを更新します。

+0

しかし、効率の低い操作を引き起こす可能性がある場合、なぜ中間的な関連エンティティは良いアプローチですか?例えばあなたのアプローチで。トランザクションが更新されると、トランザクションに関連付けられたすべてのPersonオブジェクトを更新する必要があることがよくあります。私のアプローチを使用する場合、私はそれを必要としませんか?アソシエーションエンティティを使用する方が良い理由は何ですか? – thejaz

+0

あなたがやっていることのどちらが良い選択かもしれませんが、私の答えは要約データを計算する特定の問題に焦点を当てています。特定の要求を満たすために少数以上のエンティティをロードする必要がある場合は、リクエストからそのプロセスを抽出し、値が変更されたときなど、他の方法で構築する必要があるでしょう。 – SingleNegationElimination

+0

概要データは一例にすぎません。私はしばしば、実際には同じPerson * Transaction * TransactionPersonループになるすべての人をトランザクションに入れたいと思っています。これは、(TransactionPersonを追加したり編集したりした場合)もっと稀です。トランザクションにそのデータ(人のリスト)をキャッシュする必要があるとしても、それは私の質問で提案したものと同じですが、関係データもリストに追加するだけです。重複したデータにつながることはありません。どうしますか? – thejaz

1

はい、維持されている注文に依存することができます。 docsから:

エンティティがクエリとget()によって返される場合、リストプロパティの値は、格納されたときと同じ順序になります。ただし、BlobとTextの値はリストの最後に移動されます。しかし、それらは互いに対して元の順序を保持する。

2.はい、ListPropertiesはリレーションシップを非正規化するためのお友達です。私はデータをたくさん複製し、このように正規化されていないデータの 'キャッシュ'などのリストプロパティを使用する傾向があります。

+0

(2)については、データを複製するとどういう意味ですか?私の場合、それは複製ではなく、実在性のデータを保存するための唯一の方法ですか? – thejaz

+0

ときどき私は正規化された設定を保持していますが、 'AはたくさんのBを持っていますが、' B 'を保存するたびに、後で処理するために重要なデータの一部を 'A'のリストにキャッシュします。 –

関連する問題