在App-Engine中,存储元组列表的最佳性能方式是什么?

10

当存储和检索包含元组列表的数据存储实体时,最有效的存储方式是什么?

当我遇到这个问题时,元组可以是任何东西,从键值对到日期时间和样本结果,再到(x, y)坐标。
元组的数量是可变的,并且范围从1到几百个。

包含这些元组的实体需要快速/廉价地引用,而元组值不需要被索引。

我遇到过这个问题几次,并以多种不同的方式解决了它。

Method 1:

将元组值转换为字符串,并使用某些分隔符将它们连接在一起。

def PutEntity(entity, tuples):
  entity.tuples = ['_'.join(tuple) for tuple in tuples]
  entity.put()

优点:在Datastore Viewer中结果易于阅读,所有数据可以一次性获取。

缺点:可能会存在精度损失,需要程序员进行反序列化/序列化,以字符串格式存储数据需要更多的字节。

方法2:

将每个元组值存储在列表中,并使用zip/unzip函数处理元组。

def PutEntity(entity, tuples):
  entity.keys = [tuple[0] for tuple in tuples]
  entity.values = [tuple[1] for tuple in tuples]
  entity.put()

优点:精度不会丢失,虽然在Datastore查看器中数据的查看有点困难,但仍然可以查看,可以强制执行类型,所有数据可以在一次获取中获取。
缺点:程序员需要将元组进行压缩/解压缩或者仔细维护列表顺序。

方法3:

将元组列表序列化为json、pickle或协议缓冲区等格式,存储到blob或文本属性中。

优点:可用于对象和更复杂的对象,较小的bug风险,不易错配元组值。
缺点:访问Blob store需要额外的获取操作?无法在Datastore查看器中查看数据。

方法4:

将元组存储在另一个实体中,并保留键列表。

优点:架构更加明显。如果实体是视图,则不再需要保留两份元组数据。
缺点:需要两个获取操作,一个是为了实体和键列表,一个是为了元组。

我想知道哪种方法的性能最好,是否有我没有想到的方法?

谢谢, Jim

1个回答

5
我使用第三种方法。Blobstore可能需要额外的获取,但db.BlobProperty不需要。对于那些重要的对象,需要以与存储时完全相同的方式出现,我使用PickleProperty(可以在tipfy和其他一些实用库中找到)。对于我只需要保存状态的对象,我编写了一个JsonProperty函数,它的工作原理类似于PickleProperty(但显然使用SimpleJson)。对于我来说,在App Engine中,单个获取所有数据并且容易操作比CPU性能更重要。根据Google I/O有关AppStats的演讲,前往数据存储区几乎总是比本地解析更昂贵。

我倾向于使用PickleProperty的第三种方法,但有时无法通过Datastore Viewer查看实体选项会很痛苦。 - systempuntoout

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接