最后更新:
我有一些时间来实际测试这一点,首先创建 1024 个实体,每个实体都有一个包含 100KB 随机 8 位数据的 Blob 属性,等待五天让所有统计信息在 AppEngine 控制台中更新,然后替换属性每个实体上都有 200KB 的随机 8 位数据。Quota Details下Datastore Stored Data的差异和Datastore Statistics下Total Size的差异正好是 100MB,因此没有开销。如果数据采用 UTF-8 编码,则差异为 150MB。
所以答案是:
AppEngine 数据存储区将 8 位二进制数据存储为没有编码的纯 8 位字节。
好的...
附注:配额中Datastore Stored Data的“1 GByte”对应于 1024 3个字节(GB 的原始定义,现在通常称为 GiB),而不是 10 9(Giga 的公制解释)。耶!为我们的钱增加 7.3% 的存储空间!这就是为什么我比西部数据更喜欢谷歌...... :)
原始答案:
我终于找到了一些稀疏的文档来阐明这个问题:
数据存储区定义了一组它支持的数据类型:str、int32、int64、double 和 bool。
这部分文档指出“[i]在内部,所有str值都是 UTF-8 编码并按 UTF-8 代码点排序”。1
现在, Types and Property Classes的 Python 2文档将Blob类定义为“内置str类型的子类”,并说“此值存储为字节字符串,不编码为文本”。
虽然这远不是 100% 清楚的(“未编码为文本”真的意味着“未编码为 UTF-8”吗?),但似乎表明数据在物理保存时确实保留为数据存储中的 8 位字节。
与其说这是一个比@dragonx 更好的答案,我会将此作为进一步证明他是正确的证据,特别是因为我完全同意他的说法,即“[这将是] 一开始是一个迟钝的想法,它会谷歌以这种方式实施它是相当迟钝的”。
也许有一天我会做一个实际的测试。在那之前,我希望谷歌确实没有被削弱。数据存储中任何二进制数据的 50% 存储成本开销应该足以让他们尝试避免......
旁白:
1这就是为什么我首先担心这个话题。
2这可能是我错过此信息的原因。等效的Java 文档并没有真正提到这一点。
更新:
找到了更多的支持证据:
在“属性”部分末尾的“实体表”部分中途,它说:
“在内部,App Engine 将实体存储在协议缓冲区中,这是序列化结构化数据的有效机制;有关更多详细信息,请参阅开源项目页面。”
开源项目包含一个名为CodedOutputStream.java的文件(我认为)它负责实际组装构成存储协议缓冲区的二进制数据。它定义了两个方法:writeString(...)
和writeByteArray(...)
,它们都调用各自的write...NoTag(...)
方法。
我们writeStringNoTag(...)
终于找到了对字符串进行 UTF-8 编码的行:
final byte[] bytes = value.getBytes("UTF-8");
此行在 中不存在writeByteArrayNoTag(...)
。
我认为这意味着以下几点:
现在,这是否足以与“[i] 在内部,所有 str值都是 UTF-8 编码”和“二进制数据 [...] 是内置str类型的子类”相矛盾,这明确暗示二进制数据也是UTF-8编码的吗?
我认同...