【问题标题】:Allowed characters in AppEngine Datastore key nameAppEngine 数据存储区密钥名称中允许的字符
【发布时间】:2014-09-23 21:49:29
【问题描述】:

如果我 create a named key 在 Google AppEngine 中使用,key-name 是什么类型的 String?它是使用 Unicode 字符还是二进制字符串?

更具体地说,如果我想让我的键名由 8 位二进制数据组成,有什么方法可以做到吗?如果没有,我至少可以使用 7 位二进制数据吗?还是有任何保留值?例如,它是否使用 NULL 作为 End-Of-String 标记?

【问题讨论】:

    标签: google-app-engine character-encoding key google-cloud-datastore


    【解决方案1】:

    GAE 文档没有对键名字符串指定任何限制。所以任何内容的字符串应该是有效的。

    如果您想使用二进制数据作为标识符,则应将其编码为字符串。您可以使用任何binary-to-text encoding 方法:最常用的似乎是 Base64(3 个字节 = 4 个字符)和 BinHex(1 个字节 = 2 个字符)。

    【讨论】:

    • 我遇到了一个重要的限制:A name matching regex '__.*__' is reserved/read-only(参见entity.proto,它定义了键的协议缓冲区布局)
    • non-UT8 和 '/' 字符和数字 cloud.google.com/datastore/docs/best-practices#keys
    【解决方案2】:

    与此同时,我有一些时间来实际测试这一点,方法是生成一堆具有二进制名称的键,然后执行仅类型查询以取回所有键。结果如下:

    • 任何二进制字符都可以。如果您创建一个键名为 "\x00\x13\x127\x255" 的实体,查询将找到该实体,其键名将返回相同的字符串
    • AppEngine 仪表板、数据库查看器和其他工具将简单地忽略不可显示的字符,因此键名 "\x00test"\x00\x00test 都将显示为单独的实体,但它们的键都显示为 @ 987654329@
    • 没有测试了所有可用的 AppEngine 工具,仅测试了控制台中的一些基础知识,因此可能还有其他工具会被这些键混淆...
    • 密钥采用 UTF-8 编码,因此 128 到 255 之间的任何字符都占用 2 个字节的存储空间

    据此,我会得出以下建议:

    • 如果您需要能够使用 AppEngine 控制台中的单个实体并需要通过密钥识别它们,则您只能使用可打印字符,因此需要将二进制密钥名称编码为 Base16 (十六进制;50% 开销)、Base64(33% 开销)或Base85(25% 开销)
    • 如果您不关心密钥的可读性,但需要以最少的存储使用将尽可能多的数据打包到密钥名称中,请使用 Base128 编码(即仅 7 位;14% 开销)以避免隐式 UTF 8 位数据数据的 -8 编码(50% 开销!)

    旁白:

    我会接受@PeterKnego 的回答而不是这个回答,因为这个回答基本上只是确认和扩展了他已经正确假设的内容。

    通过查看 source code of the Java API,我认为键名的 UTF-8 编码发生在 API 中(在构建 protocol buffer 时)而不是 BigTable ,所以如果你真的想在存储空间最大化上发疯,也许可以构建自己的协议缓冲区并存储完整的 8 位数据而无需开销。但这可能是自找麻烦……

    【讨论】:

      猜你喜欢
      • 2010-12-29
      • 2020-01-14
      • 1970-01-01
      • 2010-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-02
      • 1970-01-01
      相关资源
      最近更新 更多