我观看了来自Google I / O 2009的视频:http://www.youtube.com/watch?v=AgaL6NGpkB8 Brett展示了微博的例子。他描述了两种数据存储模式:
第一个一个:
class Message(db.Model):
sender = db.StringProperty()
body = db.TextProperty()
receivers = db.StringListProperty()
和第二一:
class Message(db.Model):
author = db.StringProperty()
message = db.TextProperty()
class MessageIndex(db.Model)
receivers = db.StringListProperty()
并且他说,在第一个示例中,数据存储区必须在每次我们通过接收器查询消息时序列化/反序列化接收器属性,而在第二个例子中则没有。我无法理解为什么数据存储区在这个例子中表现不同,在这两种情况下接收器只是StringListProperty。你可以解释一下吗?
答案 0 :(得分:2)
在他的演讲中,他假设当你查询时,你想要检索消息的内容 - '发送者'和'身体'。在App Engine中,实体作为一个整体进行反序列化 - 您不能只加载某些字段 - 因此当您在第一个示例中执行查询时,它必须加载整个接收器列表。
在第二个示例中,您可以通过MessageIndex执行仅密钥查询,然后获取并加载相应的Message实体。因为您从不将任何MessageIndex属性加载到内存中,所以您不需要反序列化与它们关联的大而昂贵的列表属性。
答案 1 :(得分:0)
请注意,新功能投影查询可让您获取实体的部分视图,但仅限于索引属性。
https://developers.google.com/appengine/docs/python/datastore/projectionqueries
它在内部的工作原理是,您的实体,键和索引都存储在不同的表中。如果你得到整个实体,你必须在主实体表中进行查找,这是昂贵的,因为它必须反序列化整个事物(以及与该表中的任何其他进程混淆的内容)。
投影查询类似于键查询,除了实体键之外,它使用一组索引值作为键(因为这是索引表在内部运行的方式)。如果你想要一个数据子集并且可以证明付费以使其被索引(或者如果它已被索引),那么投影查询将是快速且便宜的;它只查看索引表,不需要触摸实体或键表。