在App-Engine中存储元组列表的最佳性能方式是什么?
在存储和获取一个包含元组列表的数据实体时,最有效的存储方式是什么呢?
我遇到过这个问题,元组可以是键值对、日期时间和样本结果,或者是 (x, y) 坐标。
元组的数量是可变的,从1个到几百个都有。
包含这些元组的实体需要能够快速且便宜地被引用,而元组的值不需要被索引。
我遇到过这个问题几次,并用不同的方法解决过。
方法1:
把元组的值转换成字符串,并用某种分隔符把它们连接在一起。
def PutEntity(entity, tuples):
entity.tuples = ['_'.join(tuple) for tuple in tuples]
entity.put()
优点:在数据存储查看器中结果易于阅读,所有数据一次性获取。
缺点:可能会丢失精度,程序员需要进行反序列化/序列化,存储字符串格式的数据需要更多的字节。
方法2:
把每个元组的值存储在一个列表中,并对元组进行压缩/解压。
def PutEntity(entity, tuples):
entity.keys = [tuple[0] for tuple in tuples]
entity.values = [tuple[1] for tuple in tuples]
entity.put()
优点:没有精度损失,虽然有点复杂但仍然可以在数据存储查看器中查看数据,可以强制类型,所有数据一次性获取。
缺点:程序员需要压缩/解压元组,或者小心维护列表中的顺序。
方法3:
以某种方式(比如json、pickle、协议缓冲区)序列化元组列表,并将其存储在一个二进制大对象或文本属性中。
优点:可以与对象和更复杂的对象一起使用,减少了元组值不匹配的错误风险。
缺点:访问二进制大对象需要额外的获取?无法在数据存储查看器中查看数据。
方法4:
把元组存储在另一个实体中,并保留一个键的列表。
优点:架构更清晰。如果这个实体是一个视图,我们就不需要保留两份元组数据。
缺点:需要两次获取,一次获取实体和键列表,一次获取元组。
我想知道有没有人知道哪种方法性能最好,或者有没有我没想到的其他方法?
谢谢,
吉姆
1 个回答
我使用的是方法三。Blobstore 可能需要额外的获取操作,但 db.BlobProperty 就不需要。对于那些需要确保从存储中取出时和放入时完全一样的对象,我使用 PickleProperty(可以在 tipfy 和一些其他工具库中找到)。
对于那些我只需要保存状态的对象,我写了一个 JsonProperty 函数,它的工作方式类似于 PickleProperty(但显然是使用 SimpleJson)。
对我来说,能够一次性获取所有数据,并且确保操作简单易懂,比 CPU 性能更重要(在 App Engine 上)。根据 Google I/O 关于 AppStats 的讲座,访问数据存储几乎总是比一些本地解析要贵。