2009-10-12 52 views
1

我看过从谷歌的I/2009 O此视频:http://www.youtube.com/watch?v=AgaL6NGpkB8其中布雷特显示微博的例子。他介绍了两种数据存储模式:

第一一个:
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。你能解释一下吗?GAE数据存储列表属性系列化

回答

2

在他的谈话,他假定当您查询,您要检索的消息的内容 - “发件人”和“体”。在App Engine中,实体是作为一个整体反序列化的 - 您不能只加载某些字段 - 因此,当您在第一个示例中执行查询时,它必须加载整个接收者列表。

在第二个例子,可以做在一个MessageIndex仅钥查询,然后取和加载相应的消息的实体。因为您从不将任何MessageIndex属性加载到内存中,所以不需要反序列化与它们关联的大型且昂贵的listproperty。

+0

我的理解它了,但还是谢谢你:)。你是绝对正确的。 – giolekva 2009-10-29 18:57:00

0

请注意,有一个新功能,投影查询,这可以让你得到你的实体的局部视图,但仅限于索引属性。

https://developers.google.com/appengine/docs/python/datastore/projectionqueries

它的内部工作原理,是你的实体键和索引都存储在不同的表。如果你得到整个实体,你必须在主实体表中进行查找,这是很昂贵的,因为它必须对整个事物进行反序列化(并且对该表中的任何其他进程都进行了反序列化)。

投影查询就像是一个关键的查询,但不是你的实体按键,它使用一组索引值的一个关键(因为这是如何的索引表的内部操作)。如果你想要一个数据的子集并且可以证明支付是为了索引它(或者它已经被编入索引),那么投影查询将会很快并且便宜。它只在索引表中查找,不需要触及实体或关键字表。

+0

PS - 列表属性非常昂贵,因为它会在列表中的索引表PER项中创建一个条目。这样你可以运行一个==查询并返回任何匹配项。这是您想要避免的de/serialization的昂贵部分。这不仅仅是实体de /序列化变得昂贵;它是使用列表属性更新值的写入量(如果不小心手动声明索引,则两个列表属性将呈指数形式)。 – Ajax 2013-01-04 13:38:30