我的应用程序中有两个模型,即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查询交易。
问题
答案 0 :(得分:2)
我怀疑你正在解决错误的问题。中间关联实体是一种很好的方法。你遇到的问题是摘要需要很长时间来计算;你应该更关心那个;
首选方法是提前计算摘要数据。
在“每人交易总数”的特定情况下,这意味着您希望向Person模型添加额外字段,并使用其所有事务的运行总计更新它。您可以在修改TransactionPerson时更新此值,以便汇总值始终正确。
答案 1 :(得分:1)
1。是的,您可以依赖维护的订单。来自docs:
当查询和get()返回实体时,列表属性值的顺序与存储时的顺序相同。有一个例外:Blob和Text值被移动到列表的末尾;但是,他们保持相对于彼此的原始秩序。
2。是的,ListProperties是你的关系非规范化的朋友。我倾向于大量复制数据,并以这种方式使用像去除规范化数据的“缓存”这样的列表属性。