我想以列表的形式构建具有属性的模型。
class Data(db.Model):
listOfIntergers = db.ListProperty(int)
listOfStrings = db.ListProperty(str)
在两个列表中,我想保留范围< 0,255>范围内的值列表。
属性类型将占用更少的空间,包括数据存储中的index listOfIntergers或listOfStrings?
考虑str可以是字符或编码的十六进制值,即0 = 0,255 = ff。
答案 0 :(得分:3)
小心!首先,整数使用可变长度编码进行编码,因此并非所有int64值都占用8个字节 - 小值占用1-2个字节。但是,列表属性的表示重复列表中每个值的属性名称。我使用NDB重写了您的示例(因为用于获取编码的protobuf的API更容易记住)并找到以下内容:
>>> from ndb import *
>>> class Data(Model):
... listOfIntegers = IntegerProperty(repeated=True)
... listOfStrings = StringProperty(repeated=True)
...
>>> len(Data()._to_pb().Encode())
20
>>> len(Data(listOfIntegers=[0]*100)._to_pb().Encode())
2420
>>> len(Data(listOfIntegers=[255]*100)._to_pb().Encode())
2520
>>> len(Data(listOfStrings=['\x00']*100)._to_pb().Encode())
2420
但请注意欺骗性:值为0的100个整数每个值占用24个字节(大部分是属性名称'listOfIntegers'),但值为255的100个整数每个值占用25个字节!那是你的可变长度编码。 100个值'\ x00'的每个值也需要24个字节 - 但请注意'listOfStrings'比'listOfIntegers'短一个字符,因此1字节字符串比整数0占用1个字节,并且数量相同of space为整数255。
除非您确实需要将此字段编入索引,否则正确的解决方案可能是声明BlobProperty(不是列表/重复属性)并存储由所需字节数组成的单个字符串。
>>> class Data(Model):
... b = BlobProperty()
...
>>> d = Data(b=''.join(map(chr, range(100))))
>>> len(d._to_pb().Encode())
133
>>>
对于相同数量的信息,这几乎是紧凑的20倍! (不可否认,您可以通过使用较短的属性名称来获取列表属性版本,但它仍然会更长。)