使用Google App Engine中的关系数据对多对多进行建模

时间:2011-08-11 12:54:36

标签: python google-app-engine google-cloud-datastore

我的应用程序中有两个模型,即Transaction和Person,具有多对多的关系。每笔交易都包含人员。对于每个人,还有与该人员所连接的每个交易相关的金额。因此,我需要模拟与关系数据的多对多关系。 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)

但我发现这对性能非常不利,因为如果我需要总结所有交易中每个人的金额,我需要循环Person * Transaction * TransactionPerson次以实现“加入”,同时总结金额。

我的想法

我的想法是在交易模型中有两个列表:

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

这样我就不需要遍历每个Person的所有TransactionPerson来查找关联的Transaction。我仍然可以根据Person查询交易。

问题

  1. 这可能吗?您是否相信存储/重试时列表顺序始终相同,因此索引在列表之间同步?
  2. 这是实现与关联数据的多对多关系的好方法吗?

2 个答案:

答案 0 :(得分:2)

我怀疑你正在解决错误的问题。中间关联实体是一种很好的方法。你遇到的问题是摘要需要很长时间来计算;你应该更关心那个;

首选方法是提前计算摘要数据

在“每人交易总数”的特定情况下,这意味着您希望向Person模型添加额外字段,并使用其所有事务的运行总计更新它。您可以在修改TransactionPerson时更新此值,以便汇总值始终正确。

答案 1 :(得分:1)

1。是的,您可以依赖维护的订单。来自docs

  

当查询和get()返回实体时,列表属性值的顺序与存储时的顺序相同。有一个例外:Blob和Text值被移动到列表的末尾;但是,他们保持相对于彼此的原始秩序。

2。是的,ListProperties是你的关系非规范化的朋友。我倾向于大量复制数据,并以这种方式使用像去除规范化数据的“缓存”这样的列表属性。