简体   繁体   中英

Modelling many-to-many with relation data in Google App Engine

I have two models in my application, Transaction and Person, with a many-to-many relationship. There are persons included in each Transaction. For each person, there is also a amount connected to each Transaction the Person is connected to. Therefor I need to model a many-to-many relationship with relation data. Google suggest this approach:

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

With this approach I have a model like this:

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

But I find that very bad for performance because if I need to summarize the amount for each Person in all Transactions I need to loop Person*Transaction*TransactionPerson times to implement the "join" while summing the amounts.

MY IDEA

My idea is to have two lists in the Transaction model:

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

This way I don't need to loop through all TransactionPerson for each Person to find the associated Transaction. And I can still query Transactions based on a Person.

QUESTIONS

  1. Is this possible? Can you trust that the list order is always the same when storing/retriving so the indexes sync between the lists?
  2. Is this a good way to implement many-to-many relationship with associated data?

I suspect you're solving the wrong problem. The intermediate association entity is a good approach. The problem you have is that summaries take a long time to compute; You should be concerned more about that;

The preferred approach is to calculate the summary data ahead of time .

In the specific case of "Transaction totals per Person" that would mean you want to add an extra field to the Person model and update it with a running total of all of their transactions. You would update this any time a TransactionPerson is modified, so that the summary value is always correct.

1. Yes, you can rely on the order being maintained. From the docs :

when entities are returned by queries and get(), the list properties values are in the same order as when they were stored. There's one exception to this: Blob and Text values are moved to the end of the list; however, they retain their original order relative to each other.

2. Yes, ListProperties are your friends for de-normalizing relationships. I tend to duplicate data a lot, and use list-properties like 'caches' of de-normalized data in this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM