【问题标题】:GAE datastore list property serializationGAE 数据存储列表属性序列化
【发布时间】:2013-01-04 21:35:29
【问题描述】:

我在 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。你能解释一下吗?

【问题讨论】:

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


    【解决方案1】:

    在他的演讲中,他假设当您查询时,您想要检索消息的内容 - 'sender' 和 'body'。在 App Engine 中,实体作为一个整体被反序列化 - 您不能只加载某些字段 - 所以当您在第一个示例中执行查询时,它必须加载整个接收者列表。

    在第二个示例中,您可以对 MessageIndex 执行仅键查询,然后获取并加载相应的 Message 实体。因为您从不将任何 MessageIndex 属性加载到内存中,所以您不需要反序列化与它们关联的大而昂贵的 list 属性。

    【讨论】:

    • 我已经明白了,但还是谢谢:)。你是绝对正确的。
    【解决方案2】:

    请注意,有一项新功能,即投影查询,可让您获得实体的部分视图,但仅限于索引属性。

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

    它的内部运作方式是,您的实体、键和索引都存储在不同的表中。如果您获得整个实体,则必须在主实体表中进行查找,这很昂贵,因为它必须反序列化整个事物(以及该表中的任何其他进程的内容)。

    投影查询类似于键查询,但它使用一组索引值作为键而不是实体键(因为这就是索引表在内部的操作方式)。如果您想要一个数据子集并且可以证明付费将其编入索引(或者如果它已经编入索引),那么投影查询将既快速又便宜;它只在索引表中查找,不需要接触实体或键表。

    【讨论】:

    • PS - 列表属性非常昂贵,因为它会在列表中的每个项目的索引表中创建一个条目。这样,您可以运行 == 查询并取回任何匹配的项目。这是您要避免的反序列化的昂贵部分。不仅仅是实体反序列化变得昂贵;这是使用列表属性更新值所需的写入量(如果您不小心手动声明索引,则两个列表属性将呈指数增长)。
    猜你喜欢
    • 2011-08-26
    • 2011-06-11
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多