Моделирование «многие ко многим» с данными отношений в Google App Engine - PullRequest
6 голосов
/ 11 августа 2011

У меня в приложении две модели: транзакция и персона с отношением «многие ко многим».Есть люди, включенные в каждую транзакцию.Для каждого человека есть также сумма, связанная с каждой транзакцией, к которой он подключен.Поэтому мне нужно смоделировать отношения многие ко многим с данными отношений.Google предлагает такой подход:

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)

Но я считаю, что это очень плохо для производительности, потому что если янеобходимо суммировать сумму для каждого Лица во всех Транзакциях, которые мне нужны для того, чтобы циклически обрабатывать данные о Лице * Транзакция * Транзакция-Персона при суммировании сумм.1014 * Моя идея состоит в том, чтобы в модели транзакций было два списка:

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

Таким образом, мне не нужно циклически просматривать все TransactionPerson для каждого человека, чтобы найти связанную транзакцию.И я все еще могу запрашивать транзакции, основанные на персоне.

ВОПРОСЫ

  1. Возможно ли это?Можете ли вы поверить, что порядок хранения списков всегда одинаков, поэтому индексы синхронизируются между списками?
  2. Является ли это хорошим способом реализации связи «многие ко многим» со связанными данными?

Ответы [ 2 ]

2 голосов
/ 11 августа 2011

Я подозреваю, что вы решаете не ту проблему. Промежуточный объект объединения - хороший подход. Проблема в том, что для вычисления сводок требуется много времени; Вы должны быть обеспокоены больше об этом;

Предпочтительным подходом является предварительное вычисление сводных данных .

В конкретном случае «Сумма транзакций на человека» это означает, что вы хотите добавить дополнительное поле в модель «Человек» и обновить его с помощью промежуточного итога всех их транзакций. Вы будете обновлять это всякий раз, когда TransactionPerson изменяется, так что итоговое значение всегда будет правильным.

1 голос
/ 11 августа 2011

1. Да, вы можете рассчитывать на поддержание заказа. Из документов :

когда объекты возвращаются запросами и get (), значения свойств списка располагаются в том же порядке, в котором они были сохранены. Есть одно исключение: значения Blob и Text перемещаются в конец списка; однако они сохраняют свой первоначальный порядок относительно друг друга.

2. Да, ListProperties - ваши друзья для нормализации отношений. Я часто дублирую данные и использую таким образом свойства списков, такие как «кеши» ненормализованных данных.

...